2019-2020nowcoder牛客寒假基础2

余生长醉 提交于 2020-02-06 22:08:55

12点四十起床饭都没恰,温州阴郁的天气隐隐暗示了今天的基调

https://ac.nowcoder.com/acm/contest/3003#question

A.做游戏

石头剪刀布wa两发娱乐一下,int的read加起来的时候在右边炸了一回,重新写sclll没抄对,甚至样例都没过就直接上了,这脑残的行径能怪谁呢

#include <cstdio>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <queue>
#include <set>
#include <map>
#include <stack>
 
using namespace std;
#define scd(a) scanf("%d",&a)
#define scdd(a,b) scanf("%d%d",&a,&b)
#define scddd(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define scl(a) scanf("%lld",&a)
#define scll(a,b) scanf("%lld%lld",&a,&b)
#define sclll(a,b,c) scanf("%lld%lld%lld",&a,&b,&c)
#define prl(a) printf("%lld\n",a)
#define prd(a) printf("%d\n",a)
#define prf(a) printf("%lf\n",a)
#define ptd(a) printf("%d ",a)
#define scf(a) scanf("%lf",&a)
#define scff(a,b) scanf("%lf%lf",&a,&b)
#define scfff(a,b,c) scanf("%lf%lf%lf",&a,&b,&c)
#define rint register int
#define mem(a) memset(a,0,sizeof(a))
#define rush() int T;scd(T);while(T--)
#define lc(i) (i<<1)
#define rc(i) (i<<1|1)
#define mp make_pair
#define lowbit(x) (x&(-x))
typedef long long ll;
typedef double db;
inline int read() {char c=getchar();int x=0,f=1;while(c<'0'||c>'9') {if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}return x*f;}
int main () {
    ll a,b,c,x,y,z;
    sclll(a,b,c);
    sclll(x,y,z);
    ll ans = 0;
    ans = min(a,y) + min(b,z) + min(c,x);
    prl(ans);
    return 0;
}
View Code

B.排数字

题意:一个可以重排的字符串,重排的子串可能包含616的最大个数

思路:贪心地6161616个数连续两个6可以贡献1,1可以贡献为1,取最小值

#include <cstdio>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <queue>
#include <set>
#include <map>
#include <stack>

using namespace std;
#define scd(a) scanf("%d",&a)
#define scdd(a,b) scanf("%d%d",&a,&b)
#define scddd(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define scl(a) scanf("%lld",&a)
#define scll(a,b) scanf("%lld%lld",&a,&b)
#define sclll(a,b,c) scanf("%lld%lld%lld",&a,&b,&c)
#define prl(a) printf("%lld\n",a)
#define prd(a) printf("%d\n",a)
#define prf(a) printf("%lf\n",a)
#define ptd(a) printf("%d ",a)
#define scf(a) scanf("%lf",&a)
#define scff(a,b) scanf("%lf%lf",&a,&b)
#define scfff(a,b,c) scanf("%lf%lf%lf",&a,&b,&c)
#define rint register int
#define mem(a) memset(a,0,sizeof(a))
#define rush() int T;scd(T);while(T--)
#define lc(i) (i<<1)
#define rc(i) (i<<1|1)
#define mp make_pair
#define lowbit(x) (x&(-x))
typedef long long ll;
typedef double db;
inline int read() {char c=getchar();int x=0,f=1;while(c<'0'||c>'9') {if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}return x*f;}
const int maxn = 2e5 + 10;
char s[maxn];
int main () {
    int n = read();
    scanf("%s",s + 1);
    int c1 = 0, c6 = 0;
    for (int i = 1; i <= n; ++i) {
        if (s[i] - '0' == 1) c1++;
        else if (s[i] - '0' == 6)c6++;
    }
    prd(min(c6-1,c1));
    return 0;
}
View Code

C.算概率

题意:概率a/b%(1e9 + 7) == p, 即p满足 p*b%(1e9 + 7) = a, pi就可以代表第i个题目正确的概率,问考生正确各题的概率为多少。

思路:错误的概率(1-a/b)=(b-a)/b,对其%(1e9 + 7),设答案为q,q*b%(1e9 + 7) = b-a,那么加上上面 p*b%(1e9 + 7) = a,(q + p)*b%(1e9 + 7) = b,所以可以得到(q + p) % (1e9 + 7) == 1,则q = 1-p+(1e9 + 7),至于两概率之乘积%(1e9 + 7)和两概率对应的 p 值是相等的也好证明,

要证(a1 * a2)/(b1 * b2) % (1e9 + 7) == p1*p2

只需证(b1 * b2) * (p1 * p2) % (1e9 + 7) == a1 * a2

等价于(b1 * p1) * (b2 * p2) % (1e9 + 7) == a1 * a2

等价于(b1 * p1) * (b2 * p2) % (1e9 + 7) == (b1 * p1) % (1e9 + 7) * (b2 * p2) % (1e9 + 7) = a1 * a2

以上是yy的证明过程,实际上我并没有做出来这道DP,想得有点偏,但是队友做出来了,那就厚颜无耻地贴过来了,dp[x][y],代表做了x道题,其中对了y道,那么做新的题目的时候,其结果要么是正确的要么是错误的,方程在这了 dp[x][y] = dp[x-1][y-1]*a[i] + dp[x-1][y] * (1e9 + 7 + 1 - a[i]);

#include <cstdio>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <queue>
#include <set>
#include <map>
#include <stack>

using namespace std;
#define scd(a) scanf("%d",&a)
#define scdd(a,b) scanf("%d%d",&a,&b)
#define scddd(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define scl(a) scanf("%lld",&a)
#define scll(a,b) scanf("%lld%lld",&a,&b)
#define sclll(a,b,c) scanf("%lld%lld%lld",&a,&b,&c)
#define prl(a) printf("%lld\n",a)
#define prd(a) printf("%d\n",a)
#define prf(a) printf("%lf\n",a)
#define ptd(a) printf("%d ",a)
#define scf(a) scanf("%lf",&a)
#define scff(a,b) scanf("%lf%lf",&a,&b)
#define scfff(a,b,c) scanf("%lf%lf%lf",&a,&b,&c)
#define rint register int
#define mem(a) memset(a,0,sizeof(a))
#define rush() int T;scd(T);while(T--)
#define lc(i) (i<<1)
#define rc(i) (i<<1|1)
#define mp make_pair
#define lowbit(x) (x&(-x))
typedef long long ll;
typedef double db;
inline int read() {char c=getchar();int x=0,f=1;while(c<'0'||c>'9') {if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}return x*f;}
const int maxn = 2e3 + 10;
const ll mod = 1e9 + 7;
int n;
ll a[maxn];
ll dp[maxn][maxn];
int main () {
    n = read();
    for (int i = 1; i<=n; ++i) scl(a[i]);
    dp[1][0] = mod + 1 - a[1];
    for (int i = 2; i<=n; ++i)
        dp[i][0] = dp[i-1][0] * (mod + 1 - a[i]) % mod;
    dp[1][1] = a[1];
    for (int i = 2; i<=n; ++i) {
        for (int j = 1; j<=i; ++j) {
            dp[i][j] = (dp[i-1][j-1]*a[i]%mod + dp[i-1][j]*(mod + 1 - a[i])%mod)%mod;
        }
    }
    for (int i = 0; i<=n; ++i) {
        printf("%lld ",dp[n][i]%mod);
    }puts("");
    return 0;
}
View Code

D.数三角

题意:在一个平面上给最多500个点,问其中能组成钝角三角形的个数

思路:觉得吧应该有很多种做法,下午是先确定了底边,再确定另外一个顶点是否能跟底边组成钝角三角形(余弦定理),当然三角形的前提是三点不共线(行列式),行列式想了半天,线代忘记得差不多了...详细做法代码里有

#include <cstdio>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <queue>
#include <set>
#include <map>
#include <stack>

using namespace std;
#define scd(a) scanf("%d",&a)
#define scdd(a,b) scanf("%d%d",&a,&b)
#define scddd(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define scl(a) scanf("%lld",&a)
#define scll(a,b) scanf("%lld%lld",&a,&b)
#define sclll(a,b,c) scanf("%lld%lld%lld",&a,&b,&c)
#define prl(a) printf("%lld\n",a)
#define prd(a) printf("%d\n",a)
#define prf(a) printf("%lf\n",a)
#define ptd(a) printf("%d ",a)
#define scf(a) scanf("%lf",&a)
#define scff(a,b) scanf("%lf%lf",&a,&b)
#define scfff(a,b,c) scanf("%lf%lf%lf",&a,&b,&c)
#define rint register int
#define mem(a) memset(a,0,sizeof(a))
#define rush() int T;scd(T);while(T--)
#define lc(i) (i<<1)
#define rc(i) (i<<1|1)
#define mp make_pair
#define lowbit(x) (x&(-x))
typedef long long ll;
typedef double db;
inline int read() {char c=getchar();int x=0,f=1;while(c<'0'||c>'9') {if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}return x*f;}
const int maxn = 2e5 + 10;
struct node {
    ll x, y;
}p[550];
int n;
ll line(node a, node b) {
    return (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * ((a.y - b.y));
}
ll check(int A, int B, int C) {
    ll a =line(p[B],p[C]);
    ll b =line(p[A],p[C]);
    ll c =line(p[B],p[A]);
    return a + b - c;
}
ll hanglieshi(int i, int j, int k) {
    ll x1 = p[i].x - p[j].x;
    ll y1 = p[i].y - p[j].y;
    ll x2 = p[i].x - p[k].x;
    ll y2 = p[i].y - p[k].y;
    return x1 * y2 - x2 * y1;
}
int main () {
    n = read();
    for (int i = 1; i <= n; ++i) {
        scll(p[i].x, p[i].y);
    }
    ll ans = 0;
    for (int i = 1; i <= n; ++i) {
        for (int j = i + 1; j <= n; ++j) {//确定两个点并且不会重复对底边计数
            for (int k = 1; k <= n; ++k) {
                if (k == j || k == i) continue;
                if (check(i,j,k) < 0 && hanglieshi(i,j,k) != 0) {//前面通过勾股定理的变形或者说是余弦定理的变形后面是通过行列式确定三点不共线
                    ans++;
                }
            }
        }
    }
    prl(ans);
    return 0;
}
View Code

E.做计数

题意:满足i*j<=n的i和j,能够满足根号i+根号j=根号k,k是任意正整数

思路:暴力肯定会T,for i for j 判断, 直接O(n2)暴毙,打个表或者是看得出来就会发现,答案只跟完全平方数有关,然后想到每添加一个完全平方数,通过分析,对答案的贡献数为完全平方数的因子数,这样就把答案变成了O(n)

#include <cstdio>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <queue>
#include <set>
#include <map>
#include <stack>

using namespace std;
#define scd(a) scanf("%d",&a)
#define scdd(a,b) scanf("%d%d",&a,&b)
#define scddd(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define scl(a) scanf("%lld",&a)
#define scll(a,b) scanf("%lld%lld",&a,&b)
#define sclll(a,b,c) scanf("%lld%lld%lld",&a,&b,&c)
#define prl(a) printf("%lld\n",a)
#define prd(a) printf("%d\n",a)
#define prf(a) printf("%lf\n",a)
#define ptd(a) printf("%d ",a)
#define scf(a) scanf("%lf",&a)
#define scff(a,b) scanf("%lf%lf",&a,&b)
#define scfff(a,b,c) scanf("%lf%lf%lf",&a,&b,&c)
#define rint register int
#define mem(a) memset(a,0,sizeof(a))
#define rush() int T;scd(T);while(T--)
#define lc(i) (i<<1)
#define rc(i) (i<<1|1)
#define mp make_pair
#define lowbit(x) (x&(-x))
typedef long long ll;
typedef double db;
inline int read() {char c=getchar();int x=0,f=1;while(c<'0'||c>'9') {if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}return x*f;}
const int maxn = 2e5 + 10;
ll solve(ll x) {
    set<ll>se;
    for (ll i = 1; i * i <= x; ++i) {
        if (x % i==0)se.insert(i),se.insert(x/i);
    }
    return se.size();
}
int main () {
    const ll lim = 4e7;
    ll i = 1;
    ll n = i;
    scl(n);
    ll ans = 0;
    for (ll i = 1; i * i <= n; ++i) {
        ans += solve(i * i);
    }
    prl(ans);
    return 0;
}
View Code

F.拿物品

题意:一个物品有两个属性,分别只对两个玩家有效

思路:假设原本两个玩家都可以拿得到所有物品,一个玩家拿走一个物品就相当于把一个物品对自己有利的属性加起来,并且使对对方有利的属性无法获得

#include <cstdio>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <queue>
#include <set>
#include <map>
#include <stack>

using namespace std;
#define scd(a) scanf("%d",&a)
#define scdd(a,b) scanf("%d%d",&a,&b)
#define scddd(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define scl(a) scanf("%lld",&a)
#define scll(a,b) scanf("%lld%lld",&a,&b)
#define sclll(a,b,c) scanf("%lld%lld%lld",&a,&b,&c)
#define prl(a) printf("%lld\n",a)
#define prd(a) printf("%d\n",a)
#define prf(a) printf("%lf\n",a)
#define ptd(a) printf("%d ",a)
#define scf(a) scanf("%lf",&a)
#define scff(a,b) scanf("%lf%lf",&a,&b)
#define scfff(a,b,c) scanf("%lf%lf%lf",&a,&b,&c)
#define rint register int
#define mem(a) memset(a,0,sizeof(a))
#define rush() int T;scd(T);while(T--)
#define lc(i) (i<<1)
#define rc(i) (i<<1|1)
#define mp make_pair
#define lowbit(x) (x&(-x))
typedef long long ll;
typedef double db;
inline int read() {char c=getchar();int x=0,f=1;while(c<'0'||c>'9') {if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}return x*f;}
const int maxn = 2e5 + 10;
struct node {
    ll a, b, id, sum;
}p[maxn];
bool cmp(node a, node b){
    return a.sum > b.sum;
}
ll ans1[maxn],ans2[maxn],tot1,tot2;
int main () {
    int n;
    scd(n);
    for (int i = 1; i<=n; ++i) scl(p[i].a);
    for (int i = 1; i<=n; ++i) scl(p[i].b);
    for (int i = 1; i<=n; ++i) p[i].id = i;
    for (int i = 1; i<=n; ++i) p[i].sum = p[i].a + p[i].b;
    sort(p+1,p+1+n,cmp);
    tot1 = tot2 = 0;
    for (int i = 1; i<=n; ++i){
        if(i&1){
            ans1[++tot1] = p[i].id;
        }
        else ans2[++tot2] = p[i].id;
    }
    for (int i = 1; i <= tot1; ++i) printf("%lld%c", ans1[i],i==tot1?'\n':' ');
    for (int i = 1; i <= tot2; ++i) printf("%lld%c", ans2[i],i==tot2?'\n':' ');
    
    return 0;
}
View Code

G.判正误

对大佬们来说显然是easy,什么hash啥的,又是魔幻操作,意想不到的是pow居然可以直接过,编译器果然是博大精深,法力无边。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a,b,c,d,e,f,g;
const ll mod = 1e9 + 7;
ll qpow(ll a, ll b){
    ll r = 1;
    while (b) {
        if (b&1) {
            r = (r * a) % mod;
        }
        b>>=1;
        a = (a * a) %mod;
    }
    return r;
}
int main(){
    int t;scanf("%d",&t);
    while (t--){
        scanf("%lld%lld%lld%lld%lld%lld%lld",&a,&b,&c,&d,&e,&f,&g);
        ll aa = qpow(a,d);
        ll bb = qpow(b,e);
        ll cc = qpow(c,f);
        g = g % mod;
        if (aa + bb + cc == g % mod) {
            puts("Yes");
        } else puts("No");
    }
    return 0;
}
View Code

H施魔法

I建通道

J求函数

施魔法

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!