(2015年郑州轻工业学院ACM校赛题)H 五子棋

时间:2023-03-09 07:57:14
(2015年郑州轻工业学院ACM校赛题)H 五子棋

我们最后选题策略失败,选到五子棋这题,没想到这题非常麻烦,最后也没做出来!

比赛结束后发了题解再做才做出来! 不得不说 这题真的很麻烦

一个需要比较细致分类讨论的题目。判定棋盘是否合法应考虑如下几种情况:
• 黑先手,因此白子不可能多于黑子,且两种石子数量之差不超过 1;
• 如果黑胜,当前黑子比白子多 1;
• 如果白胜,当前黑白石子数量相等;
• 两方不能同时胜利,即不能出现两方同时有五子相连的情况;
将上述情况判定清楚后,如果没有一方有五子相连则输出 other,否则对于胜的一方,枚举它最后
一步放的是哪个棋子。如果存在这样一个棋子,将它拿走之后局面上就没有五子连珠了,那么我们就可
以到达这个局面(证明略),那么就输出相应的棋子颜色;如果不存在的话(例如棋盘上有 10 个连续的
黑子)则说明局面非法,直接输出 fault 即可。

#include<stdio.h>
#include<iostream>
#include<stack>
#include<queue>
#include<math.h>
#include<stdlib.h>
#include<cstring>
#include<algorithm>
using namespace std;
#define Max(a,b) (a>b?a:b)
#define Min(a,b) (a<b?a:b)
#define INF 0xfffffff
#define maxn 110
#define WHITE 1
#define BLACK 2
#define FAULT 3
#define OTHER 4
int n, m, num;
char maps[maxn][maxn];
int dir[][] = { {-,-},{-,},{-,},{,-} }; void Search(int x,int y,char ch,int k)
{
num ++;
int nx = x + dir[k][];
int ny = y + dir[k][]; if(nx >= && nx < n && ny >= && ny < m && maps[nx][ny] == ch )
Search(nx, ny, ch, k);
} int MaxNum(char ch)
{
int ans = ;
for(int i=; i<n; i++)
{
for(int j=; j<m; j++)
{
if(maps[i][j] == ch)
{
for(int k=; k<; k++)
{
num = ;
Search(i,j,ch,k);
ans = max(ans,num);
}
}
}
}
return ans;
} bool Fault(char ch)
{
int i, j, k, p, nx, ny;
for(i=; i<n; i++)
{
for(j=; j<m; j++)
{
if( maps[i][j] == ch )
{
for(k=; k<; k++)
{
num = ;
Search(i,j,ch,k);
if(num >= )
{
for(p=; p<; p++)
{
nx = i + dir[k][] * p;
ny = j + dir[k][] * p;
maps[nx][ny] = '.';
} if(MaxNum(ch) >= )
return true; for(p=; p<; p++)
{
nx = i + dir[k][] * p;
ny = j + dir[k][] * p;
maps[nx][ny] = ch;
} }
}
}
}
}
return false;
} int Slove()
{
int White = , Black = ;
int MaxWhite = , MaxBlack = ;
int i, j;
for(i=; i<n; i++)
{
for(j=; j<m; j++)
{
if(maps[i][j] == '')
White ++;
if(maps[i][j] == '')
Black ++;
}
} MaxWhite = MaxNum('');
MaxBlack = MaxNum(''); if(MaxWhite > || MaxBlack > || Black-White >= || Black < White )
return FAULT; if(Fault('')||Fault('') || (MaxWhite >= && MaxBlack >= ) || (MaxWhite >= && Black != White)|| (MaxBlack >= && Black- != White))
return FAULT;
if(MaxWhite >= && Black == White)
return WHITE;
if(MaxBlack >= && Black- == White)
return BLACK; return OTHER; } int main()
{
int T, i, ans;
cin >> T; while(T--)
{
cin >> n >> m; for(i=; i<n; i++)
cin >> maps[i]; ans = Slove(); if(ans == WHITE)
printf("white\n");
else if(ans == BLACK)
printf("black\n");
else if(ans == OTHER)
printf("other\n");
else
printf("fault\n");
}
return ;
}