zoukankan      html  css  js  c++  java
  • Codeforces 584

    链接:https://codeforces.com/contest/584


    A - Olesya and Rodion - [水]

    题解:注意到 $t$ 的范围是 $[2,10]$,对于位数小于 $2 imes 3 imes cdots imes 10 = 3628800$ 的数,暴力枚举去找;否则就直接在 $3628800$ 后面补零即可。

    AC代码:

    #include<bits/stdc++.h>
    using namespace std;
    int n,t;
    int p10[8];
    int main()
    {
        ios::sync_with_stdio(0);
        
        cin>>n>>t;
        if(n>=7)
        {
            cout<<3628800;
            for(int i=8;i<=n;i++) cout<<0;
            cout<<endl;
        }
        else
        {
            p10[0]=1;
            for(int i=1;i<8;i++) p10[i]=p10[i-1]*10;
    
            bool ok=0;
            for(int x=p10[n-1];x<p10[n];x++)
            {
                if(x%t==0)
                {
                    cout<<x<<endl;
                    ok=1;
                    break;
                }
            }
            if(!ok) cout<<-1<<endl;
        }
    }

    B - Kolya and Tanya - [组合数]

    题解:对于一个等边三角形上的三个人,有 $20$ 种方案使得和不等于 $6$,有 $7$ 种方案使得和等于 $6$,然后很容易得到公式 $sum_{i=1}^{n} C_{n}^{i} cdot 20^i cdot 7^{n-i}$。

    AC代码:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const ll mod=1e9+7;
    int n;
    ll fpow(ll a,ll n)
    {
        ll res=1,base=a%mod;
        while(n)
        {
            if(n&1) res*=base, res%=mod;
            base*=base, base%=mod;
            n>>=1;
        }
        return res%mod;
    }
    ll inv(ll n){return fpow(n,mod-2);}
    
    int main()
    {
        ios::sync_with_stdio(0);
        cin.tie(0), cout.tie(0);
    
        cin>>n;
        ll ans=0;
        ll C=1ll, A=1ll, B=fpow(7ll,n);
        for(int i=1;i<=n;i++)
        {
            C=C*(n+1-i), C%=mod;
            C=C*inv(i), C%=mod;
    
            A*=20ll, A%=mod;
            B*=inv(7), B%=mod;
    
            ans+=((C*A)%mod)*B%mod, ans%=mod;
        }
        cout<<ans<<endl;
    }

    C - Marina and Vasya - [字符串]

    题解:

    要有 $t$ 个不同字符,就是要有 $n-t$ 个相同字符;对于 $s_1,s_2$ 两个字符串,如果存在 $s_1[i] = s_2[i]$ 就尽量让 $s_3[i]$ 也是这个字符。如果直接就能把 $n-t$ 个要求相同的字符全搞定了,剩下的就可以乱放。

    如果还剩下来 $n-t-same$(此处 $same$ 代表 $s_1,s_2$ 中相同位置且相同字符的数目),要求有这么多个相同字符。那记 $diff$ 代表 $s_1,s_2$ 中相同位置但不同字符的数目,讨论一下 $2(n-t-same)$ 与 $diff$ 的关系即可。

    AC代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1e5+5;
    int n,t;
    string s1,s2,s3;
    bool f[maxn];
    int same,diff;
    inline char Find(char x,char y)
    {
        if(x!='a' && y!='a') return 'a';
        if(x!='b' && y!='b') return 'b';
        if(x!='c' && y!='c') return 'c';
    }
    int main()
    {
        ios::sync_with_stdio(0);
        cin.tie(0), cout.tie(0);
    
        cin>>n>>t; t=n-t;
        cin>>s1>>s2;
    
        for(int i=0;i<n;i++) s3+='0';
    
        int diff=0;
        for(int i=0;i<n;i++)
        {
            if(s1[i]!=s2[i]) diff++;
            if(s1[i]==s2[i] && t>0)
            {
                s3[i]=s1[i];
                t--;
            }
        }
    
        if(t>0)
        {
            if(2*t>diff) s3="-1";
            else
            {
                int cnt=0;
                for(int i=0;i<n;i++)
                {
                    if(s3[i]!='0') continue;
                    s3[i]=s1[i], cnt++;
                    if(cnt==t) break;
                }
                cnt=0;
                for(int i=0;i<n;i++)
                {
                    if(s3[i]!='0') continue;
                    s3[i]=s2[i], cnt++;
                    if(cnt==t) break;
                }
    
                for(int i=0;i<n;i++)
                {
                    if(s3[i]!='0') continue;
                    s3[i]=Find(s1[i],s2[i]);
                }
            }
        }
        else
        {
            for(int i=0;i<n;i++)
            {
                if(s3[i]!='0') continue;
                s3[i]=Find(s1[i],s2[i]);
            }
        }
    
        cout<<s3<<endl;
    }

    D - Dima and Lisa - [简单数论]

    题解:

    有一个命题:不小于 $6$ 的偶数都能表示成两个质数的和,然后 $4$ 可以表示成 $2+2$。

    所以,我们只要让 $p_1 = 3$,那么剩下来 $n-3$ 必为偶数,就能找到两个质数加起来等于它,这要求最少也要筛 $1 sim 5e8$ 的素数,会MLE。

    因此,我们可以找出 $1e8,2e8,cdots,9e8$ 这些数字附近的一个素数,然后例如 $n = 5e8+6e7$ 时,我们可以选 $p_1 = 5e8+9$,这样剩下来 $n - (5e8+9)$ 这个数的范围就保证在 $1 sim 1e8$ 之间,然后我们只需要筛 $1 sim 1e8$ 之间的素数就可以了。

    AC代码:

    #include<bits/stdc++.h>
    using namespace std;
    typedef pair<int,int> P;
    int n;
    
    const int MAX=1e8+50;
    int cnt,prime[MAX/10];
    bool isPrime[MAX+5];
    void Screen() //欧拉筛法求素数
    {
        cnt=0;
        memset(isPrime,1,sizeof(isPrime));
        isPrime[0]=isPrime[1]=0;
        for(int i=2;i<=MAX;i++)
        {
            if(isPrime[i]) prime[cnt++]=i;
            for(int j=0;j<cnt;j++)
            {
                if(i*prime[j]>MAX) break;
                isPrime[i*prime[j]]=0;
                if(i%prime[j]==0) break;
            }
        }
    }
    
    P Find(int sum)
    {
        int p1=0, p2=cnt-1;
        while(p1<=p2 && prime[p1]+prime[p2]!=sum)
        {
            if(prime[p1]+prime[p2]>sum) p2--;
            else p1++;
        }
        return make_pair(prime[p1],prime[p2]);
    }
    
    int D[9]={(int)9e8-37,(int)8e8-1,(int)7e8+1,(int)6e8+1,(int)5e8+9,(int)4e8+9,(int)3e8+7,(int)2e8-9,(int)1e8+7};
    
    int main()
    {
        Screen();
    
        cin>>n;
    
        if(n==3)
        {
            printf("1
    ");
            printf("3
    ");
            return 0;
        }
        if(n==4)
        {
            printf("2
    ");
            printf("2 2
    ");
            return 0;
        }
        if(n==5)
        {
            printf("2
    ");
            printf("2 3
    ");
            return 0;
        }
        if(n==6)
        {
            printf("3
    ");
            printf("2 2 2
    ");
            return 0;
        }
    
        for(int i=0;i<9;i++)
        {
            if(n-D[i]>=4)
            {
                P res=Find(n-D[i]);
                printf("3
    ");
                printf("%d %d %d
    ",D[i],res.first,res.second);
                return 0;
            }
        }
    
        P res=Find(n-3);
        printf("3
    ");
        printf("3 %d %d
    ",res.first,res.second);
    }

    E - Anton and Ira - [贪心]

  • 相关阅读:
    【转】解决在Android设备播放音频与其他应用重音的问题,并监听耳机的控制按钮
    【转】wamp 3.0.6(apache 2.4.23) 403 forbidden 解决办法
    身份证第18位(校验码)的计算方法
    【转】Win10开机密码忘了?教你破解Win10开机密码
    【转】具透 | 你可能不知道,iOS 10 有一个中国「特供」的联网权限功能
    钉钉自定义机器人 发送文本 换行 无效果
    屏蔽右键+f12
    【转】理解WebKit和Chromium: JavaScript引擎简介
    第2章 排序 | 第10节 计数排序练习题 && 基数排序
    图像处理-深入探索插值操作
  • 原文地址:https://www.cnblogs.com/dilthey/p/10542910.html
Copyright © 2011-2022 走看看