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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/guhaiteng/article/details/51995418

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

题意:。。。。

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

#include <bits/stdc++.h>
#define ll __int64
using  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 __int64
using  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 __int64
using  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 __int64
using  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;
}


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




展开阅读全文

没有更多推荐了,返回首页