Codeforces Round #324 (Div. 2) (B排列组合)(C贪心)(D哥德巴赫猜想 数论+暴力)

来源:互联网 发布:vmware esxi mac os 编辑:程序博客网 时间:2024/06/08 17:47

传送门:A. Olesya and Rodion   (水题)

题意:。。。。

思路:刚开始还想用什么字符串模拟或者大数什么的,后来想了想差点笑出声来,样例就是用来忽悠人的。。。

#include <bits/stdc++.h>#define ll __int64using  namespace  std;const int inf=0x3f3f3f3f;int  n,t;int  main(){//    freopen("in.txt", "r", stdin);//    freopen("out.txt", "w", stdout);    while(~scanf("%d %d",&n,&t)){        if(t==10){            if(n==1)printf("-1\n");            else{                printf("1");n--;                for(int i=1 ; i<=n ; i++)printf("0");                printf("\n");            }        }        else{            for(int i=1 ; i<=n ; i++)printf("%d",t);            printf("\n");        }    }    return 0;}
传送门:B. Kolya and Tanya    (排列组合)

题意:

在一个圆上,3n个点依次标号,然后标号为i,i+n,i+2n的点连成三角形。然后每个点分配一个值(在1-3范围内)。然后只要有一个

三角形的点的值的和不为6就成功。问有多少种分配方案。

思路

排列组合。总共3^3n个可能,减去7^n个不可能的结果。因为要么是222要么是123才能有6,然后222只有1种123可以6种,加起来一个三角形的不成功的情况有7种。

#include <bits/stdc++.h>#define ll __int64using  namespace  std;const ll mod=1e9+7;ll n;ll pow_mod(ll x, ll n , ll mod){    ll res=1;    while(n>0){        if(n&1)res=res*x%mod;        x=x*x%mod;        n>>=1;    }    return res;}int  main(){//    freopen("in.txt", "r", stdin);//    freopen("out.txt", "w", stdout);    while(~scanf("%I64d",&n)){        printf("%I64d\n",(pow_mod(27LL,n,mod)-pow_mod(7LL,n,mod)+mod)%mod);    }    return 0;}
传送门:C. Marina and Vasya   (贪心)

题意

给你两个字符串,要求你构造出第三个字符串,使得第三个字符串和第一个字符串和第二个字符串的不同个数,都是k个

思路:先尽量考虑重叠的情况,然后交替染色就好了

#include <bits/stdc++.h>#define ll __int64using  namespace  std;const int inf=0x3f3f3f3f;const   int  N=1e5+5;int n,t,cnt=0;char s1[N],s2[N],s3[N];bool flag=true,vis[N];void  solve(){    if(cnt==t)return ;    for(int i=0 ; i<n ;i++){        if(s1[i]==s2[i]){            s3[i]=s1[i];            vis[i]=true;            cnt++;            if(cnt==t)return ;        }    }    for(int i=0 ; i<n ;i++){//只能交替染色,如果是s1[i]!=s2[i]三个字符串最多只有两个对应位字符相等        if(s1[i]!=s2[i]){            if(flag)s3[i]=s1[i];            else  s3[i]=s2[i];            vis[i]=true;            flag=!flag;            if(flag)cnt++;//交替染完一次色            if(cnt==t)return ;        }    }}int  main(){//    freopen("in.txt", "r", stdin);//    freopen("out.txt", "w", stdout);    scanf("%d %d",&n,&t);    scanf("%s",s1);    scanf("%s",s2);    t=n-t;    solve();    s3[n]='\0';    if(cnt<t){ puts("-1");return  0;}    for(int i=0 ; i<n ; i++){        if(!vis[i]){            for(char j='a' ; j<='z' ; j++){                if(s1[i]!=j&&s2[i]!=j){                    s3[i]=j;vis[i]=true;                    break;                }            }        }    }    printf("%s\n",s3);    return 0;}


传送门:D. Dima and Lisa    (数论,暴力)

题意:给你一个奇数n
你可以见这个素数拆分成1,2或3个素数的和,将其输出,结果不唯一。

思路:
题源是哥德巴赫猜想
任一大于2的偶数都可写成两个质数之和。
任一大于7的奇数都可写成三个素数之和。


首先得知道一个数学规律,在小于10^9的素数中相邻两个素数之间的的距离不会超过300,。
知道上面的规律后解这个题暴力就行了。
通过分析我们可以知道:

1个:本身就是素数。

2个:因为给的是奇数,所以两个拆出来的数一定是一奇一偶,既是偶数又是素数的数只有2,所以我们只需判断n-2是否为素数即可。

3个:先找一个比n小的素数(尽量靠近n),根据上面的那个规律,所以我们就能很快的找到另一个素数。在做差以后得到x(x<=300),剩下的两个数就在x里面暴力寻找即可。

#include <bits/stdc++.h>#define ll __int64using  namespace  std;const int inf=0x3f3f3f3f;int n;bool  prime(int n){    for(int i=2 ; i*i<=n ; i++){        if(n%i==0)return  false;    }    return true;}int  main(){//    freopen("in.txt", "r", stdin);//    freopen("out.txt", "w", stdout);    while(~scanf("%d",&n)){        if(prime(n))printf("1\n%d",n);        else if(prime(n-2))printf("2\n2 %d",n-2);        else{            int m=n;            while(!prime(m))m--;            int t=n-m;            for(int i=2 ; i<=t ; i++){                if(prime(i)&&prime(t-i)){                    printf("3\n%d %d %d",i,t-i,m);                    break;                }            }        }    }    return 0;}

总结:这场比赛主要涉及数学知识,并没有太多高深的算法,好像最后大家的解题量都很可观~




0 0