A. 2048 Game 对于每种数字记个数,递推进位直到2048即可
#include<stdio.h> #include<map> #include<queue> #include<iostream> #include<algorithm> #include<vector> #define MOD 10000000007 using namespace std; int a[200],n,temp; int main() { int q; scanf("%d",&q); while(q--) { for(int i=0;i<=20;i++)a[i]=0; scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&temp); int cot=0; while(temp) { cot++;temp/=2; } a[cot]++; } for(int i=1;i<=11;i++)a[i+1]+=a[i]/2; if(a[12])printf("YES\n");else printf("NO\n"); } return 0; }B. Knights 这题取巧了,显然最多配对数时必然每个白色马能到达的位置都是黑色马,每个黑色马能到达的位置都是白色马,而我们知道国际象棋中,马每走一步都是从黑格到白格或白格到黑格,若把黑色马(白色马)换成黑格(白格),那么显然只需要按国际象棋棋盘的规律输出即可。 正解是个DFS,每次搜索周围8个方向即可
#include<stdio.h> char a[3]="BW"; int n; int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++)printf("%c",a[(i+j)%2]); printf("\n"); } return 0; }C. Perfect Team 显然我们需要优先把什么都不会的分配出去,然后若是coder多就优先消耗coder,mathematician多就优先消耗mathematician。
#include<stdio.h> #include<algorithm> using namespace std; int q,a,b,c,ans; int main() { scanf("%d",&q); while(q--) { scanf("%d%d%d",&a,&b,&c); if(a>b) swap(a,b); ans=min(a,c); a-=ans;b-=ans; if(b>=a*2)ans+=a; else { int te=b-a; ans+=b-a; b-=te*2; a-=te; ans+=(a/3)*2; a%=3;b%=3; ans+=(a>1); } printf("%d\n",ans); } return 0; }D. Make The Fence Great Again 盲猜是一个简单DP,然后就过了??? 显然每个 a i a_i ai最大只需要被+2,所以DP的时候分别转移 a i a_i ai不变、 a i a_i ai+1、 a i a_i ai+2的最小代价即可。
#include<stdio.h> long long min(long long a,long long b) { return a>b?b:a; } long long dp[300005][3],a[300005]; int b[300005]; int main() { int q,n; scanf("%d",&q); while(q--) { scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d%I64d",&b[i],&a[i]); dp[1][0]=0; dp[1][1]=a[1]; dp[1][2]=a[1]*2; for(int i=2;i<=n;i++) { dp[i][0]=dp[i][1]=dp[i][2]=2e18; if(b[i]!=b[i-1])dp[i][0]=min(dp[i-1][0],dp[i][0]); if(b[i]!=b[i-1]+1)dp[i][0]=min(dp[i-1][1],dp[i][0]); if(b[i]!=b[i-1]+2)dp[i][0]=min(dp[i-1][2],dp[i][0]); if(b[i]!=b[i-1]-1)dp[i][1]=min(dp[i-1][0],dp[i][1]); if(b[i]!=b[i-1])dp[i][1]=min(dp[i-1][1],dp[i][1]); if(b[i]!=b[i-1]+1)dp[i][1]=min(dp[i-1][2],dp[i][1]); if(b[i]!=b[i-1]-2)dp[i][2]=min(dp[i-1][0],dp[i][2]); if(b[i]!=b[i-1]-1)dp[i][2]=min(dp[i-1][1],dp[i][2]); if(b[i]!=b[i-1])dp[i][2]=min(dp[i-1][2],dp[i][2]); dp[i][1]+=a[i];dp[i][2]+=a[i]*2; } printf("%I64d\n",min(min(dp[n][0],dp[n][1]),dp[n][2])); } return 0; }