(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\n");

        else if(ans == BLACK)

            printf("black\n");

        else if(ans == OTHER)

            printf("other\n");

        else

            printf("fault\n");

    }

    return 0;

}

 

你可能感兴趣的:(ACM)