2015轻院校赛 H五子棋
时隔一年再次尝试写了这道题,终于a了,了解了错了十次的痛。
啥都不说了上代码!!!
#include <iostream> #include <cstring> #include <algorithm> #include <queue> #include <cstdio> #include <cstdlib> #include <cctype> #include <cmath> using namespace std; char str[111][111]; int s[111][111]; int t, n, m; int dir[8][2]={{-1,-1},{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1}}; int judge(char ch, int fff)//判断是否可以连成五子,并且用s数组标记 { int num5 = 0; for(int i=1; i<=n; i++) { for(int j=1; j<=m; j++) { if(str[i][j]==ch) { for(int i1=0; i1<4; i1++) { int x1 = i, y1 = j, x2 = i, y2 = j; int num = 1; int num1 = 0, num2 = 0; while(x1>=1&&x1<=n&&y1>=1&&y1<=m) { x1+=dir[i1][0]; y1+=dir[i1][1]; if(str[x1][y1]==ch&&x1>=1&&x1<=n&&y1>=1&&y1<=m) num1++; else break; } while(x2>=1&&x2<=n&&y2>=1&&y2<=m) { x2+=dir[i1+4][0]; y2+=dir[i1+4][1]; if(str[x2][y2]==ch&&x2>=1&&x2<=n&&y2>=1&&y2<=m) num2++; else break; } num+=num1+num2; if(num>=5) { num5++; if(fff == 1) for(int i2=1; i2<=num; i2++) { s[x2+dir[i1][0]*i2][y2+dir[i1][1]*i2] += 1; } } } } } } return num5; } int solve(char ch)//把一点改为'.'然后判断是否可以连成五子 { int ans = 0; for(int i=1; i<=n; i++) { for(int j=1; j<=m; j++) { if(str[i][j]==ch && s[i][j]>=1) { str[i][j] = '.'; ans = judge(ch, 2); if(ans==0) return 1; str[i][j] = ch; } } } return 0; } int main() { scanf("%d", &t); while(t--) { scanf("%d %d", &n, &m); for(int i=1; i<=n; i++) { scanf("%s", str[i]+1); } int sum1 = 0, sum2 = 0; for(int i=1; i<=n; i++) { for(int j=1; j<=m; j++) { if(str[i][j] =='1') sum1++; if(str[i][j] == '2') sum2++; } } int ans = 0; if(sum2<sum1 || sum2>sum1+1)//棋子个数 ans = 1; else { memset(s, 0, sizeof(s)); int num1 = judge('1', 1);//求是否可以连成五子 int num2 = judge('2', 1);//同上 if(sum1 == sum2)//个数一样多因为黑的先,所以黑的不能赢 { if(num2>0)//黑五子情况不能产生 ans = 1; else if(num1==0)//黑白都没有五子产生 ans = 4; else { int ss = solve('1');//求改掉一点是否还能连成5子,不能连成表示白赢 if(ss) ans = 2; else ans = 1; } } else { if(num1>0) ans = 1; else if(num2==0) ans = 4; else { int ss = solve('2');//求改掉一点是否可以连成5子,不能连成黑赢 if(ss) ans = 3; else ans = 1; } } } switch(ans) { case 1:printf("fault\n");break; case 2:printf("white\n");break; case 3:printf("black\n");break; default:printf("other\n"); } } return 0; }