题意:给你4*4的矩阵,两个人玩游戏,第一个人放黑棋,第二个人放白棋,每次只能放在某一列的最下面的空格处,赢得比赛的条件是行或列或斜有三个相同颜色的棋子,问假如第一个人放在(1,x)的位置,第二个人能赢的比赛并且最后棋子摆放位置在(a,b)处时整个比赛的状态数目有多少。
题解:dfs模拟下棋。
AC代码:
#include<stdio.h>
#include<algorithm>
#include<iostream>
using namespace std;
int ans,a,b,h[4],s[4],x,f[4]={1,2,4,8};
bool mark[5][5][5][5][16][16][16][16];
bool ff(int k){return k!=0;}
bool judge()
{
for(int i=0;i<2;i++)//水平
for(int j=0;j<min(h[i],min(h[i+1],h[i+2]));j++)
if(ff(s[i]&f[j])==ff(s[i+1]&f[j])&&ff(s[i+1]&f[j])==ff(s[i+2]&f[j]))
return true;
for(int i=0;i<4;i++)//垂直
for(int j=0;j<h[i]-2;j++)
if(ff(s[i]&f[j])==ff(s[i]&f[j+1])&&ff(s[i]&f[j+1])==ff(s[i]&f[j+2]))
return true;
for(int i=0;i<2;i++)//对角线
{
for(int j=0;j<2;j++)
if(h[i]>=j+1&&h[i+1]>=j+2&&h[i+2]>=j+3)
if(ff(s[i]&f[j])==ff(s[i+1]&f[j+1])&&ff(s[i+1]&f[j+1])==ff(s[i+2]&f[j+2]))
return true;
for(int j=0;j<2;j++)
if(h[i]>=j+3&&h[i+1]>=j+2&&h[i+2]>=j+1)
if(ff(s[i]&f[j+2])==ff(s[i+1]&f[j+1])&&ff(s[i+1]&f[j+1])==ff(s[i+2]&f[j]))
return true;
}
return false;
}
void dfs(int flag,int prex,int prey)
{
if(judge())
{
if(prex==b&&prey==a&&flag)
{
if(mark[h[0]][h[1]][h[2]][h[3]][s[0]][s[1]][s[2]][s[3]])return ;
mark[h[0]][h[1]][h[2]][h[3]][s[0]][s[1]][s[2]][s[3]]=true;
ans++;
}
return ;
}
for(int i=0;i<4;i++)
{
if(h[i]==4)continue;
h[i]++;
s[i]|=flag*(1<<(h[i]-1));
dfs(flag^1,i+1,h[i]);
s[i]^=flag*(1<<(h[i]-1));
h[i]--;
}
}
int main()
{
scanf("%d%d%d",&x,&a,&b);
h[x-1]=s[x-1]=1;
dfs(0,x,1);
printf("%d\n",ans);
}