A题:直接枚举
#include<stdio.h> #include<string.h> int A[110],c[110]; int main() { int n,i,j,ans,sum,x; while(scanf("%d",&n)!=EOF){ sum=x=0; memset(c,0,sizeof(c)); for(i=1;i<=n;i++) scanf("%d",&A[i]); for(i=n;i>=1;i--) c[i]=c[i+1]+A[i]; for(i=1;i<=n;i++) { ans=sum; for(j=i;j<=n;j++){ ans+=1-A[j]; if(ans+c[j+1]>x) x=ans+c[j+1]; } sum+=A[i]; } printf("%d\n",x); } return 0; }
B题:质数打表
#include<stdio.h> #include<string.h> int vis[2000000],p[200000]; void init() { int i,j; for(i=2;i<2000;i++){ if(!vis[i]){ for(j=i+i;j<2000000;j+=i){ vis[j]=1; } } } for(i=2,j=0;i<2000000;i++) if(!vis[i]) p[j++]=i; } int main() { int n,i; init(); while(scanf("%d",&n)!=EOF) { for(i=0;i<n-1;i++) printf("%d ",p[i]); printf("%d\n",p[i]); } return 0; }
C题:分析可得,枚举0或5的位置(表示此位置后面的全部去掉当前位置不去掉,前面位置随便去,此种情况的方案数为2^i),因为有k的存在,所以是一个等比数列(直接用等比数列的公式,快速幂可解)
#include<stdio.h> #include<string.h> #define _LL __int64 #define FM "%I64d" #define mod 1000000007 char s[101000]; _LL power(_LL x,_LL y) { _LL sum=1; while(y){ if(y&1) sum=(sum*x)%mod; x=(x*x)%mod; y>>=1; } return sum; } _LL k; int main() { _LL i,j; _LL n,ans,sum; while(scanf("%s",s)!=EOF) { n=strlen(s); scanf(FM,&k); for(i=n-1;i>=0;i--){ if(s[i]=='5'||s[i]=='0') break; } if(i<0){ printf("0\n"); continue; } for(j=0;j<i;j++){ if(s[j]=='5'||s[j]=='0'); else break; } if(j>=i&&i==n-1) ans=(power(2,k*n)+mod-1)%mod; else { ans=0; sum=(power(2,n*k)+mod-1)%mod*(power((power(2,n)+mod-1)%mod,mod-2))%mod; for(;i>=0;i--){ if(s[i]=='0'||s[i]=='5'){ ans=(ans+power(2,i)*sum%mod)%mod; } } } printf(FM,ans);printf("\n"); } return 0; }
D题:先bfs出联通块和并把每个联通块分层,然后从后往前一层层的去把B(除了最后一个)换成R即可;
#include<stdio.h> #include<string.h> #include<vector> #include<queue> using namespace std; char mat[510][510]; int vis[510][510],n,m; struct node { char t; int x,y; node(char a=0,int b=0,int c=0):t(a),x(b),y(c){} }st[1011000]; int op[4][2]={0,1,1,0,0,-1,-1,0}; vector <node> ans[300000]; void bfs(int x,int y) { int dep=1,tx,ty,i; queue<int> X,Y; vis[x][y]=1;X.push(x);Y.push(y); while(!X.empty()){ x=X.front();X.pop(); y=Y.front();Y.pop(); for(i=0;i<4;i++){ tx=x+op[i][0]; ty=y+op[i][1]; if(tx>n||tx<1||ty>m||ty<1||vis[tx][ty]) continue; vis[tx][ty]=vis[x][y]+1; ans[vis[tx][ty]].push_back(node('R',tx,ty)); X.push(tx);Y.push(ty); } } } int main() { int i,j,k; while(scanf("%d%d",&n,&m)!=EOF) { k=0; for(i=0;i<=n*m;i++) ans[i].clear(); memset(vis,0,sizeof(vis)); for(i=1;i<=n;i++) scanf("%s",mat[i]+1); for(i=1;i<=n;i++){ for(j=1;j<=m;j++){ if(mat[i][j]=='#') vis[i][j]=-1; else{ st[k++]=node('B',i,j); } } } for(i=1;i<=n;i++) for(j=1;j<=m;j++) if(!vis[i][j]) bfs(i,j); for(i=n*m;i>1;i--){ if(ans[i].size()){ for(j=0;j<ans[i].size();j++){ st[k]=ans[i][j];st[k++].t='D'; st[k++]=ans[i][j]; } } } printf("%d\n",k); for(i=0;i<k;i++) printf("%c %d %d\n",st[i].t,st[i].x,st[i].y); } return 0; }
E题:状态压缩,直接枚举状态转移,在不走障碍的情况下累加方案数O(n*2^n)。
#include<stdio.h> #include<string.h> #define mod 1000000007 #define _LL __int64 int sum[1<<24],dp[1<<24],A[25],H[2]; _LL N[25]; int main() { int n,i,j,m,t; N[0]=1; for(i=1;i<=14;i++) N[i]=(N[i-1]*i)%mod; while(scanf("%d",&n)!=EOF) { for(i=0;i<n;i++) scanf("%d",&A[i]); scanf("%d",&m); if(m==0) printf("%d\n",(int)N[n]); else { H[0]=H[1]=-1; for(i=0;i<m;i++) scanf("%d",&H[i]); dp[0]=1;t=1<<n;sum[0]=0; for(i=1;i<t;i++){ for(j=0;j<n;j++) if(i&(1<<j)) break; sum[i]=sum[i^(1<<j)]+A[j]; if(sum[i]==H[0]||sum[i]==H[1]) continue; dp[i]=0; for(j=0;j<n;j++){ if(i&(1<<j)){ dp[i]+=dp[i^(1<<j)]; if(dp[i]>=mod) dp[i]-=mod; } } } printf("%d\n",dp[t-1]); } } return 0; }