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;
}

 

posted @ 2016-04-14 20:10  梦中。。  阅读(160)  评论(0编辑  收藏  举报