問題描述 Alice和Bob正在玩井字棋游戲。 井字棋游戲的規則很簡單:兩人輪流往3*3的棋盤中放棋子,Alice放的是“X”,Bob放的是“O”,Alice執先。當同一種棋子占據一行、一列或一條對角線的三個格子時,游戲結束,該種棋子的持有者獲勝。當棋盤被填滿的時候,游戲結束,雙方平手。 Alice ...
問題描述 Alice和Bob正在玩井字棋游戲。
井字棋游戲的規則很簡單:兩人輪流往3*3的棋盤中放棋子,Alice放的是“X”,Bob放的是“O”,Alice執先。當同一種棋子占據一行、一列或一條對角線的三個格子時,游戲結束,該種棋子的持有者獲勝。當棋盤被填滿的時候,游戲結束,雙方平手。
Alice設計了一種對棋局評分的方法:
- 對於Alice已經獲勝的局面,評估得分為(棋盤上的空格子數+1);
- 對於Bob已經獲勝的局面,評估得分為 -(棋盤上的空格子數+1);
- 對於平局的局面,評估得分為0;
例如上圖中的局面,Alice已經獲勝,同時棋盤上有2個空格,所以局面得分為2+1=3。
由於Alice並不喜歡計算,所以他請教擅長編程的你,如果兩人都以最優策略行棋,那麼當前局面的最終得分會是多少? 輸入格式 輸入的第一行包含一個正整數T,表示數據的組數。
每組數據輸入有3行,每行有3個整數,用空格分隔,分別表示棋盤每個格子的狀態。0表示格子為空,1表示格子中為“X”,2表示格子中為“O”。保證不會出現其他狀態。
保證輸入的局面合法。(即保證輸入的局面可以通過行棋到達,且保證沒有雙方同時獲勝的情況)
保證輸入的局面輪到Alice行棋。 輸出格式 對於每組數據,輸出一行一個整數,表示當前局面的得分。 樣例輸入 3
1 2 1
2 1 2
0 0 0
2 1 1
0 2 1
0 0 2
0 0 0
0 0 0
0 0 0 樣例輸出 3
-4
0 樣例說明 第一組數據:
Alice將棋子放在左下角(或右下角)後,可以到達問題描述中的局面,得分為3。
3為Alice行棋後能到達的局面中得分的最大值。
第二組數據:
Bob已經獲勝(如圖),此局面得分為-(3+1)=-4。
第三組數據:
井字棋中若雙方都採用最優策略,游戲平局,最終得分為0。 數據規模和約定 對於所有評測用例,1 ≤ T ≤ 5。
雙方均使用最優策略,所以Alice會去尋找當前局面所有著法中使分數最大的著法,Bob會去尋找當前局面中所有著法使分數最小的著法。
使用com函數遞歸查找,得到結果後在數組中記錄該著法得到的局面的分數,再尋找裡面的最值,由形參中註明當前局面輪到誰走棋決定尋找最大值或最小值。
#include<iostream> using namespace std; int lef (int a[]){//¼ÆËãÆåÅÌÉÏ»¹ÓжàÉÙ¿Õ°×λ int i=0,flag=0; for(;i<9;i++){ if(a[i]==0){ flag++; } } return flag; } int show(int a[]){//´òÓ¡Æå¾Ö for(int i=0;i<9;i++){ cout<<a[i]<<" "; } cout<<endl; return 0; } int win1(int a[]){//ÅжÏʤ¸º£¬Èç¹ûûÓÐÃ÷È·½á¹û·µ»Ø0 if((a[1]*a[2]*a[0]==1) || (a[3]*a[4]*a[5]==1) || (a[6]*a[7]*a[8]==1) || (a[0]*a[3]*a[3]*a[6]*a[6]==1) || (a[1]*a[4]*a[4]*a[7]*a[7]==1) || (a[2]*a[8]*a[5]==1) || (a[0]*a[4]*a[8]==1) || (a[2]*a[6]*a[4]==1) ){ return 1; }else if((a[1]*a[2]*a[0]==8) || (a[3]*a[4]*a[5]==8) || (a[6]*a[7]*a[8]==8) || (a[0]*a[3]*a[6]==8) || (a[1]*a[4]*a[7]==8) || (a[2]*a[8]*a[5]==8) || (a[0]*a[4]*a[8]==8) || (a[2]*a[6]*a[4]==8) ){ return 2; }else return 0; } int com(int a[],int b){ if(win1(a)==1){ return lef(a)+1; }else if (win1(a)==2) { return -lef(a)-1;} if(lef(a)==0){ return 0; } int k,j,c[9],d[9],mmm=-1000;//ÓÃÊý×écÀ´±£´æµ±Ç°¾ÖÃæÒԱ㸴ԣ¬Êý×éd±£´æµÃ·ÖÇé¿ö for(k=0;k<9;k++){ c[k]=a[k]; d[k]=0; } if(b==1){ for(j=0;j<9;j++){ if(c[j]==0){ c[j]=1; d[j]=com(c,2); c[j]=0; } } for(k=0;k<9;k++){ if(d[k]>=mmm && c[k]==0){ mmm=d[k]; } } return mmm; }else if (b==2){ mmm=1000; for(j=0;j<9;j++){ if(c[j]==0){ c[j]=2; d[j]=com(c,1); c[j]=0; } } for(k=0;k<9;k++){ if(d[k]<=mmm && c[k]==0){ mmm=d[k]; } } return mmm; } return 0; } int main(){ int i,k,l,t; cin>>t; int data[9],result[100]; for (i=0;i<t;i++){ for(k=0;k<9;k++){ cin>>data[k]; } result[i]=com(data,1); } for(i=0;i<t;i++){ cout<<result[i]<<endl; } return 0; }