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 - [贪心]

  • 相关阅读:
    图片上传-下载-删除等图片管理的若干经验总结3-单一业务场景的完整解决方案
    图片上传-下载-删除等图片管理的若干经验总结2
    HDU 1195 Open the Lock
    HDU 1690 Bus System
    HDU 2647 Reward
    HDU 2680 Choose the best route
    HDU 1596 find the safest road
    POJ 1904 King's Quest
    CDOJ 889 Battle for Silver
    CDOJ 888 Absurdistan Roads
  • 原文地址:https://www.cnblogs.com/dilthey/p/10542910.html
Copyright © 2011-2022 走看看