CCF-CSP-201803-4 棋局評估
問題描述
試題編號: | 201803-4 |
試題名稱: | 棋局評估 |
時間限制: | 1.0s |
記憶體限制: | 256.0MB |
問題描述: |
問題描述 Alice和Bob正在玩井字棋遊戲。 例如上圖中的局面,Alice已經獲勝,同時棋盤上有2個空格,所以局面得分為2+1=3。 由於Alice並不喜歡計算,所以他請教擅長程式設計的你,如果兩人都以最優策略行棋,那麼當前局面的最終得分會是多少? 輸入格式 輸入的第一行包含一個正整數T,表示資料的組數。 輸出格式 對於每組資料,輸出一行一個整數,表示當前局面的得分。 樣例輸入 3 樣例輸出 3 樣例說明 第一組資料: 資料規模和約定 對於所有評測用例,1 ≤ T ≤ 5。 |
遞歸回溯所有可能的情況。
①Alice勝評估得分是正的,取最大值
②Bob勝評估得分是負的,取最小值
③平局是0分
AC程式碼:
#include<iostream>
#include<string>
using namespace std;
int cb[4][4];//chessbocbrd
bool isvictory(int k)//判斷k是否贏了,k=1代表cblice,k=2代表bob;
{
int i;
for(i=1;i<=3;i++)
{
if((cb[i][1]==cb[i][2])&&(cb[i][2]==cb[i][3])&&(cb[i][3]==k))return true; //一行
if((cb[1][i]==cb[2][i])&&(cb[2][i]==cb[3][i])&&(cb[3][i]==k))return true; //一列
}
if((cb[1][1]==k)&&(cb[2][2]==k)&&(cb[3][3]==k))return true;//主對角
if((cb[1][3]==k)&&(cb[2][2]==k)&&(cb[3][1]==k))return true;//副對角
return false; //其他情況
}
int dfs(int k)//輪到k下棋,判斷棋盤局勢,返回最終狀態的得分
{
int t=0;
for(int i=1;i<=3;i++)
for(int j=1;j<=3;j++)
if(cb[i][j]==0) t++; //計算出棋盤中空格數
if(k==1&&isvictory(2))return -t-1; //因為bob贏了,要加上一個負號;
if(k==2&&isvictory(1))return t+1;
if(t==0) return 0; //平局
int mn=10000000,mx=-10000000;
for(int i=1;i<=3;i++)
for(int j=1;j<=3;j++)
if(cb[i][j]==0)//對每一個空格進行模擬;
{
cb[i][j]=k;
if(k==1) mx=max(mx,dfs(2));//這個就是為了要滿足最優下棋策略的語句,就是alice會選擇下一步最優的解;
if(k==2) mn=min(mn,dfs(1));//同理
cb[i][j]=0;//回溯前面的狀態;
}
//進行到這一步,對所有空格都進行了模擬,返回相應的最值
if(k==1) return mx;
if(k==2) return mn;
}
int main()
{
int ans,n;
cin>>n;
while(n--)
{
for(int i=1;i<=3;i++)
for(int j=1;j<=3;j++)
cin>>cb[i][j];
ans=dfs(1); //Alice先下棋
cout<<ans<<endl;
}
return 0;
}