uvalive4836(枚举)

题意:

给出一个五子棋的棋面,问先手或者后手是否能够在三步之内必胜。


思路:

只有三次下子,我们可以枚举下的位置,分为以下三种情况:

①、先手在第一步就能获胜,说明棋面内有4子相连。

②、后手在第二步的时候获胜,说明棋面上后手有至少两个4子相连的情况。

③、先手在第三步的时候获胜,这时,先手在走第一步的时候,可能后手有一个4子相连,或者没有4子相连,如果有一个,那么先手就要去堵截,否则先手可以任意下子,接下来,后手走第二步,这时候我们就可以用②来判断先手是否必胜。


代码:

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#include<climits>

using namespace std;

int a[20][20],nx,ny;
char b[][10]={"white","black"};

int judge(int now)
{
    for(int i=0;i<15;i++)
        for(int j=0;j<15;j++)
        {
            if(i<11&&j<11)
                if(a[i][j]==now&&a[i+1][j+1]==now
                &&a[i+2][j+2]==now&&a[i+3][j+3]==now
                &&a[i+4][j+4]==now)
                    return 1;
            if(i<11)
                if(a[i][j]==now&&a[i+1][j]==now
                &&a[i+2][j]==now&&a[i+3][j]==now
                &&a[i+4][j]==now)
                    return 1;
            if(j<11)
                if(a[i][j]==now&&a[i][j+1]==now
                &&a[i][j+2]==now&&a[i][j+3]==now
                &&a[i][j+4]==now)
                    return 1;
            if(i>3&&j<11)
                if(a[i][j]==now&&a[i-1][j+1]==now
                &&a[i-2][j+2]==now&&a[i-3][j+3]==now
                &&a[i-4][j+4]==now)
                    return 1;
        }
    return 0;
}

int judge1(int now)
{
    int num=0,ok;
    for(int i=0;i<15;i++)
        for(int j=0;j<15;j++)
            if(a[i][j]<0)
            {
                a[i][j]=now;
                ok=judge(now);
                a[i][j]=-1;
                if(ok)
                {
                    nx=i;
                    ny=j;
                    return 1;
                }
            }

    return 0;
}

int judge2(int now)
{
    int num=0,ok;
    for(int i=0;i<15;i++)
        for(int j=0;j<15;j++)
            if(a[i][j]<0)
            {
                a[i][j]=!now;
                ok=judge(!now);
                a[i][j]=-1;
                if(ok)
                {
                    num++;
                    nx=i;
                    ny=j;
                    if(num==2)
                        return num;
                }
            }

    return num;
}

int judge3(int now)
{
    int ok;
    if(judge2(now)==1)
    {
        int i=nx;
		int j=ny;
        a[i][j]=now;
        if(judge2(!now)==2)
        {
            nx=i;
            ny=j;
            return 1;
        }
        else
            return 0;
    }
    for(int i=0;i<15;i++)
        for(int j=0;j<15;j++)
            if(a[i][j]<0)
            {
                a[i][j]=now;
                ok=judge2(!now);
                a[i][j]=-1;
                if(ok==2)
                {
                    nx=i;
                    ny=j;
                    return 1;
                }
            }    
    return 0;
}

int main()
{
	int n;
    while(scanf("%d",&n)!=EOF)
    {
        if(n==0)
			return 0;

        memset(a,-1,sizeof(a));
		int now=1;
        for(int i=0;i<n;i++)
        {
			int x,y,k;
            scanf("%d%d%d",&x,&y,&k);
            if(k)
                now--;
            else
                now++;
            a[x][y]=k;
        }
        if(now!=0&&now!=1)
        {
            printf("Invalid.\n");
            continue;
        }
        if(n<=5)
        {
            printf("Cannot win in 3 moves.\n");
            continue;
        }
        if(judge1(now))
            printf("Place %s at (%d,%d) to win in 1 move.\n",b[now],nx,ny);
        else if(judge2(now)==2)
            printf("Lose in 2 moves.\n");
        else if(judge3(now))
            printf("Place %s at (%d,%d) to win in 3 moves.\n",b[now],nx,ny);
        else
            printf("Cannot win in 3 moves.\n");
    }
    return 0;    
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值