1. 程式人生 > >Codeforces Round #324 (Div. 2) (B排列組合)(C貪心)(D哥德巴赫猜想 數論+暴力)

Codeforces Round #324 (Div. 2) (B排列組合)(C貪心)(D哥德巴赫猜想 數論+暴力)

題意:。。。。

思路:剛開始還想用什麼字串模擬或者大數什麼的,後來想了想差點笑出聲來,樣例就是用來忽悠人的。。。

#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;
}
傳送門:

題意:

在一個圓上,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;
}
傳送門:

題意

給你兩個字串,要求你構造出第三個字串,使得第三個字串和第一個字串和第二個字串的不同個數,都是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;
}


傳送門: 題意:給你一個奇數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;
}

總結:這場比賽主要涉及數學知識,並沒有太多高深的演算法,好像最後大家的解題量都很可觀~