(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[4][2] = { {-1,-1},{-1,0},{-1,1},{0,-1} };
 
void Search(int x,int y,char ch,int k)
{
    num ++;
    int nx = x + dir[k][0];
    int ny = y + dir[k][1];
 
    if(nx >= 0 && nx < n && ny >= 0 && ny < m && maps[nx][ny] == ch )
        Search(nx, ny, ch, k);
}
 
int MaxNum(char ch)
{
    int ans = 0;
    for(int i=0; i<n; i++)
    {
        for(int j=0; j<m; j++)
        {
            if(maps[i][j] == ch)
            {
                for(int k=0; k<4; k++)
                {
                    num = 0;
                    Search(i,j,ch,k);
                    ans = max(ans,num);
                }
            }
        }
    }
    return ans;
}
 
 
bool Fault(char ch)
{
    int i, j, k, p, nx, ny;
    for(i=0; i<n; i++)
    {
        for(j=0; j<m; j++)
        {
            if( maps[i][j] == ch )
            {
                for(k=0; k<4; k++)
                {
                    num = 0;
                    Search(i,j,ch,k);
                    if(num >= 5)
                    {
                        for(p=0; p<5; p++)
                        {
                            nx = i + dir[k][0] * p;
                            ny = j + dir[k][1] * p;
                            maps[nx][ny] = '.';
                        }
 
                        if(MaxNum(ch) >= 5)
                            return true;
 
                        for(p=0; p<5; p++)
                        {
                            nx = i + dir[k][0] * p;
                            ny = j + dir[k][1] * p;
                            maps[nx][ny] = ch;
                        }
 
                    }
                }
            }
        }
    }
    return false;
}
 
int Slove()
{
    int White = 0, Black = 0;
    int MaxWhite = 0, MaxBlack = 0;
    int i, j;
    for(i=0; i<n; i++)
    {
        for(j=0; j<m; j++)
        {
            if(maps[i][j] == '1')
                White ++;
            if(maps[i][j] == '2')
                Black ++;
        }
    }
 
    MaxWhite = MaxNum('1');
    MaxBlack = MaxNum('2');
 
    if(MaxWhite > 9 || MaxBlack > 9 || Black-White >= 2 || Black < White )
        return FAULT;
 
    if(Fault('1')||Fault('2') || (MaxWhite >= 5 && MaxBlack >= 5) || (MaxWhite >= 5 && Black != White)|| (MaxBlack >=5 && Black-1 != White))
        return FAULT;
    if(MaxWhite >= 5 && Black == White)
        return WHITE;
    if(MaxBlack >=5 && Black-1 == White)
        return BLACK;
 
    return OTHER;
 
}
 
int main()
{
    int T, i, ans;
    cin >> T;
 
    while(T--)
    {
        cin >> n >> m;
 
        for(i=0; i<n; i++)
            cin >> maps[i];
 
        ans = Slove();
 
        if(ans == WHITE)
            printf("white
");
        else if(ans == BLACK)
            printf("black
");
        else if(ans == OTHER)
            printf("other
");
        else
            printf("fault
");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/chenchengxun/p/4443541.html