問題描述 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; }
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/77560.html
標籤:C++
