1003 Mine
简单sg的博弈题,我们走入了nim博弈的误区,后来发现改了三四个字符就过了。。。。我只能说我是sbsbsbsbsbsb。。。判奇偶啊。。。
#pragma comment(linker,"/STACK:102400000,102400000")//用的是dfs搜索,写得挫,不加上这个且用C++交就跪了。。 #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<string> #include<cmath> #include<set> #include<vector> #define mem(a,b) memset(a,b,sizeof(a)) #define FOR(a,b,i) for(i=a;i<=b;++i) #define For(a,b,i) for(i=a;i<b;++i) #define N 9973 using namespace std; inline void RD(int &ret) { char c; do { c=getchar(); } while(c<'0'||c>'9'); ret=c-'0'; while((c=getchar())>='0'&&c<='9') { ret=ret*10+(c-'0'); } } inline void OT(int a) { if(a>=10) { OT(a/10); } putchar(a%10+'0'); } int n,m,k; int sum[1005][1005]; int used[1005][1005]; int s[1000005]; int shu,shuk,ans; int dx[9]={-1,-1,-1,0,0,1,1,1}; int dy[9]={-1,0,1,-1,1,-1,0,1}; void dfs(int x,int y)//用的就是施教主写的 {//这里的目的就是求空白部分周围的数字块数量 int i; used[x][y]=1; for(i=0;i<8;i++) { if(x+dx[i]>=0&&x+dx[i]<n&&y+dy[i]>=0&&y+dy[i]<m) { if(used[x+dx[i]][y+dy[i]]==0&&sum[x+dx[i]][y+dy[i]]==0) { dfs(x+dx[i],y+dy[i]); } } } for(i=0; i<8; i++) { if(x+dx[i]>=0&&x+dx[i]<n&&y+dy[i]>=0&&y+dy[i]<m) { if(used[x+dx[i]][y+dy[i]]==0&&sum[x+dx[i]][y+dy[i]]>0) { used[x+dx[i]][y+dy[i]]=1; shuk++; } } } } int main() { int t,cas,i,j,a,b; while(scanf("%d",&t)!=EOF) { cas=0; while(t--) { cas++; RD(n); RD(m); RD(k); for(i=0; i<n; i++) { for(j=0; j<m; j++) { sum[i][j]=0; used[i][j]=0; } } for(i=0; i<k; i++) { RD(a); RD(b); for(j=0; j<8; j++) { if(a+dx[j]>=0&&a+dx[j]<n&&b+dy[j]>=0&&b+dy[j]<m) { sum[a+dx[j]][b+dy[j]]++; } } used[a][b]=1; } shu=0; for(i=0; i<n; i++) { for(j=0; j<m;j++) { if(used[i][j]==0) { if(sum[i][j]==0)//判奇偶,如果为奇数算作两块,偶数为一块 { shuk=0; dfs(i,j); s[shu]=shuk%2+1;//就这里改了一下就AC了,哭啊 shu++; } } } } for(i=0; i<n; i++) { for(j=0; j<m; j++) { if(used[i][j]==0)//其它单独数字块各为1块 { s[shu]=1; shu++; } } } ans=0; for(i=0;i<shu;i++) { ans^=s[i];//异或一下就行了 } printf("Case #%d: ",cas); if(ans!=0) { printf("Xiemao\n"); } else { printf("Fanglaoshi\n"); } } } return 0; }
1006 String
一道求最长公共子串的水题。。。
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<string> #include<cmath> #define mem(a,b) memset(a,b,sizeof(a)) #define FOR(a,b,i) for(i=a;i<=b;++i) #define For(a,b,i) for(i=a;i<b;++i) using namespace std; inline void RD(int &ret) { char c; do { c=getchar(); } while(c<'0'||c>'9'); ret=c-'0'; while((c=getchar())>='0'&&c<='9') { ret=ret*10+(c-'0'); } } inline void OT(int a) { if(a>=10) { OT(a/10); } putchar(a%10+'0'); } char a[1005],b[1005],c[1005]; int dp1[1005][1005],dp2[1005][1005],sum[4005][2],tmp,l1,l2,l3; void lcs(char *str,int l)//求最长公共子串 { int i,j,k; FOR(1,l,i) { if(str[i]==c[1]) { k=1; for(j=i;j<=l&&k<=l3;j++) { if(str[j]==c[k]) { k++; } } if(k!=l3+1) { break; } sum[tmp][0]=i; sum[tmp][1]=j-1; tmp++; } } } int main() { int t,cas=0,i,j,x,y,ans; RD(t); while(t--) { cas++; scanf("%s%s%s",a+1,b+1,c+1); l1=strlen(a+1); l2=strlen(b+1); l3=strlen(c+1); mem(dp1,0); mem(dp2,0); FOR(1,l1,i)//dp过程 { FOR(1,l2,j) { if(a[i]==b[j]) { dp1[i][j]=dp1[i-1][j-1]+1; } else { dp1[i][j]=max(dp1[i-1][j],dp1[i][j-1]); } } } for(i=l1; i>=1; i--) { for(j=l2; j>=1; j--) { if(a[i]==b[j]) { dp2[i][j]=dp2[i+1][j+1]+1; } else { dp2[i][j]=max(dp2[i+1][j],dp2[i][j+1]); } } } tmp=0; lcs(a,l1); x=tmp; lcs(b,l2); y=tmp-x; ans=0; For(0,x,i) { For(0,y,j) { ans=max(ans,dp1[sum[i][0]-1][sum[j+x][0]-1]+dp2[sum[i][1]+1][sum[j+x][1]+1]); } } printf("Case #%d: %d\n",cas,ans+l3); } return 0; }
1004 我们队也做出来了,但我暂时还没有研究,据说是个treeDP,但貌似是枚举树的直径。。不懂啦,等待AC