【CQ18高一暑假前挑战赛2】标程
【昨晚打校赛,5个小时打完很累了,所以搞忘出题了。。。对不起学弟们,不过出的题都亲自写过一遍,可以保证题目和代码长度都不长,题目难度不大】
【A:bush博弈】
#include<bits/stdc++.h> using namespace std; int main() { int T,N,K; scanf("%d",&T); while(T--){ scanf("%d%d",&N,&K); if(N%(K+1)==0) puts("B"); else puts("A"); } return 0; }
【B:DP求最长公共子序列,可以反推前缀】
#include<bits/stdc++.h> using namespace std; const int maxn=1010; char a[maxn],b[maxn],ans[maxn]; int dp[maxn][maxn]; int main() { int L1,L2,i,j,k; scanf("%s%s",a+1,b+1); L1=strlen(a+1); L2=strlen(b+1); for(i=1;i<=L1;i++) for(j=1;j<=L2;j++){ dp[i][j]=max(dp[i-1][j],dp[i][j-1]); if(a[i]==b[j]) dp[i][j]=max(dp[i][j],dp[i-1][j-1]+1); } i=L1;j=L2;k=0; while(i>=1&&j>=1){ if(a[i]==b[j]) ans[++k]=a[i],i--,j--; else if(dp[i-1][j]>=dp[i][j-1]) i--; else j--; } for(i=k;i>=1;i--) cout<<ans[i]; return 0; }
【C:nlogn的算法求最长递增子序列】
#include<bits/stdc++.h> using namespace std; const int maxn=100100; int a[maxn]; int main() { int N,x,i,L=0,pos=0; scanf("%d",&N); for(i=1;i<=N;i++){ scanf("%d",&x); pos=upper_bound(a+1,a+L+1,x)-a; a[pos]=x; L=max(L,pos); } cout<<L<<endl; return 0; }
【D:简单处理矩阵:求最大的区间全是1】:问题转化为枚举上下边界,然后连续的一块算。
#include<bits/stdc++.h> using namespace std; const int maxn=510; int a[maxn][maxn],sum[maxn][maxn]; int main() { int N,M,i,j,k,ans=0; scanf("%d%d",&N,&M); for(i=1;i<=N;i++) for(j=1;j<=M;j++){ scanf("%d",&a[i][j]); sum[i][j]=sum[i-1][j]+a[i][j]; } for(i=1;i<=N;i++) for(j=i;j<=N;j++){ int L=0; for(k=1;k<=M;k++) if(sum[j][k]-sum[i-1][k]==j-i+1){ L++;ans=max(ans,(j-i+1)*L);} else L=0; } printf("%d\n",ans); return 0; }
【E:区间DP求最长回文,更优的算法有manecher等】
#include<bits/stdc++.h> using namespace std; const int maxn=1010; char c[maxn]; int dp[maxn][maxn]; int main() { int L,i,j,ans=0; scanf("%s",c+1); L=strlen(c+1); for(i=L;i>=1;i--){ for(j=i;j<=L;j++){ if(j-i+1==1) dp[i][j]=1; else if(j-i+1==2) dp[i][j]=(c[i]==c[j]?2:0); else if(dp[i+1][j-1]!=0&&c[i]==c[j]) dp[i][j]=dp[i+1][j-1]+2; ans=max(ans,dp[i][j]); } } printf("%d\n",ans); return 0; }
It is your time to fight!