11155 ly與lyon的終極巔峰對決
阿新 • • 發佈:2019-01-01
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; }