11155 ly与lyon的终极巅峰对决

11155 ly与lyon的终极巅峰对决

时间限制:1000MS  内存限制:65535K
提交次数:566 通过次数:130

题型: 编程题   语言: G++;GCC

Description

    从前有一天,ly与lyon在讨论人工智能里面的博弈问题,恰好,他们提到了五子棋。
当然,这里说的五子棋是指无禁手(不知道什么是禁手的也不用管了,跟这题没关系)的五子棋:
    黑先下,黑白轮流下,最先在横竖斜任一方向上形成连续的5个子(或以上)就算赢。

    对此,ly和lyon都有自己的一套判断局势的算法,并且根据自己的想法各写了一个判断局况的程序。然而,他们都觉得自己的程序要比对方的优秀,所以,
他们稍作改良,做成了自动决策的对局程序,并拿出来互相pk。目前需要一个自动判断胜负的程序,即最先出现5连子的判胜。



输入格式

    第1行输入两个数n和m,用空格分开,n为棋盘横纵坐标的最大值,m为步数:
1<=n<=1000,0<m<=n*n
    第2行到第m+1行为第一步到第m步的坐标,每行两个数,用空格分开:
x和y,1<=x,y<=n
    输入保证不存在重复下子。

(出题人LRC)


输出格式

    输出首次分出胜负那一步的序号(第一步为1),如果走完了都没有分出胜负,输出“baga”。


输入样例

5 11
3 3
2 3
2 4
4 3
4 2
3 4
1 5
3 2
5 1
1 1
1 2


输出样例

9
思路:这道题不难。关键在于如何判断每一步下完后,下棋的人能否赢。我们用一个函数去判断每一步下完后,能否是横斜竖任意方向组成连续5个棋。详细见代码。

#include <stdio.h>
#include <stdlib.h>
int black[1001][1001],white[1001][1001],n;
int judge(int test[][1001],int a,int b)//判断这一步后,各个方向能否构成连续5子
{
        int i,j,k,sum1,sum2,sum3,sum4;//sum1-4记录横,竖,45°斜,135°斜方向连续5个方向位置的值的和
        for(k=0;k<=4;k++)
        {
                sum1=sum2=sum3=sum4=0;
                for(i=a+4-k;i>=a-k;i--)//横方向
                {
                        if(i<=n&&i>=1)//保证不超过象限范围
                        sum1+=test[i][b];
                        if(sum1==5)
                                return 1;//如果可以构成连续5子,返回1
                }
                for(i=b+4-k;i>=b-k;i--)//竖方向
                {
                        if(i>=1&&i<=n)
                        sum2+=test[a][i];
                        if(sum2==5)
                                return 1;
                }
                for(i=b+4-k,j=a+4-k;i>=b-k&&j>=a-k;j--,i--)//斜方向
                {
                        if(i>=1&&i<=n&&j>=1&&j<=n)
                        sum3+=test[j][i];
                        if(sum3==5)
                                return 1;
                }
                for(i=b+4-k,j=a-4+k;i>=b-k&&j<=a+k;j++,i--)//斜方向
                {
                        if(i>=1&&i<=n&&j>=1&&j<=n)
                        sum4+=test[j][i];
                        if(sum4==5)
                                return 1;
                }

        }
        return 0;//不能则返回0
}
int main()
{
    int a,b,m,i,j,s1=0,s2=0,judge1=0,judge2=0;//s1,s2分别记录黑棋和白棋赢时是第几步,都没有赢,则都为0
    scanf("%d %d",&n,&m);
    for(i=1;i<=m;i++)
    {
        scanf("%d %d",&a,&b);
        if(i%2!=0)//单数黑棋下
                {
                        black[a][b]=1;//这个位置标记为1
                        if(s1==0)//如果s1>0了,证明已经赢了,没必要再去判断
                        {
                                judge1=judge(black,a,b);
                                if(judge1==1)
                                s1=i;
                        }
                }
        else//双数白棋
                {
                        white[a][b]=1;
                        if(s2==0)
                        {
                                judge2=judge(white,a,b);
                                if(judge2==1)
                                s2=i;
                        }
                }
    }
    if(s1>0&&s2>0)//按要求输出
    {
            if(s1>s2)
                printf("%d",s2);
            else
                printf("%d",s1);
    }
    else if(s1>s2)
        printf("%d",s1);
    else if(s1<s2)
        printf("%d",s2);
    else
        printf("baga");
    return 0;
}



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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值