Codeforces Round #324 (Div. 2) (B排列組合)(C貪心)(D哥德巴赫猜想 數論+暴力)
阿新 • • 發佈:2018-12-24
題意:。。。。
思路:剛開始還想用什麼字串模擬或者大數什麼的,後來想了想差點笑出聲來,樣例就是用來忽悠人的。。。
傳送門:#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;
}
總結:這場比賽主要涉及數學知識,並沒有太多高深的演算法,好像最後大家的解題量都很可觀~