Atcoder 349 E-Weighted Tic-Tac-Toe
题目大意
在一个被设计好的棋盘中找到最先构成一行/一列/斜线的赢家。
解题思路
显然,先手和后手都不会让对方构成一条直线就赢了,最终会造成死局,在死局中先手和后手当然也不会让对方的分数总和比对手低,所以这道题目深搜,遍历先手下在每一个位子,后手争取不输的情况
代码(注释版)
#include<bits/stdc++.h>
#define int long long
using namespace std;
int g[3][3];
int b[3][3];
int end(){
for(int i=0;i<3;i++){
if(b[i][0]==b[i][1]&&b[i][1]==b[i][2]&&b[i][2]!=0){
return b[i][0];
}
if(b[0][i]==b[1][i]&&b[1][i]==b[2][i]&&b[2][i]!=0){
return b[0][i];
}
}
if(b[0][0]==b[1][1]&&b[1][1]==b[2][2]&&b[1][1]!=0){
return b[1][1];
}
if(b[0][2]==b[1][1]&&b[1][1]==b[2][0]&&b[1][1]!=0){
return b[1][1];
}
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
if(!b[i][j]){
return 0;
}
}
}
return -1;
}
bool dfs(int cur,int s1,int s2){
int t=end();
//为什么写成!=0就对了
if(t!=0){
if(t==1) return 1;
else if(t==2) return 0;
else if(t==-1) return s1>s2;
}
if(cur){
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
if(b[i][j]==0){
b[i][j]=1;
if(dfs(0,s1+g[i][j],s2)){ //如果1赢了,那产生这一步的上一步会阻止这一步产生
b[i][j]=0;
return 1;
}
b[i][j]=0;
}
}
}
//这里如果结束还没能赢
//就是2赢了
return 0;
}
else{
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
if(b[i][j]==0){
b[i][j]=2;
if(!dfs(1,s1,s2+g[i][j])){
b[i][j]=0;
return 0;
}
b[i][j]=0;
}
}
}
return 1;
}
return 1;
}
signed main(){
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
cin>>g[i][j];
}
}
if(dfs(1,0,0)) puts("Takahashi");
else puts("Aoki");
return 0;
}