1. 程式人生 > >11155 ly與lyon的終極巔峰對決

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