下棋方案数(填空) 二进制比dfs快多了
#include<bits/stdc++.h>
using namespace std;//
const int N=100010;
typedef long long LL;
typedef pair<int,int>PII;
int a[30],g[8][8];
LL ans;
void check()
{
int pos=0;
for(int i=1;i<=5;i++)
for(int j=1;j<=5;j++)
g[i][j]=a[++pos];
//开始判断
int s1=0,s2=0,s3=0,s4=0;//这里求只要一条直线上的值是0|1代表一方获胜 s1代表行s2代表列 s3s4对角
for(int i=1;i<=5;i++)
{
s1=0,s2=0;
for(int j=1;j<=5;j++)
{
s1+=g[i][j],s2+=g[j][i];
if(i==j) s3+=g[i][j];
if(i+j==6) s4+=g[i][j];//反对角上 下标和是6
}
if(s1==0||s1==5||s2==0||s2==5) return;//不是平局
}
if(s3==0||s3==5||s4==0||s4==5) return;//不是平局
ans++;//平局了
}
int main()//分析平局一定是白13 黑12 我们把白当做1
{
//这里用二进制比dfs快多了
for(int i=0;i<=(1<<25)-1;i++)
{
int s=0,pos=0;//判断只有白起是13的时候 才可能平局 速度更快
for(int j=0;j<25;j++)
{
if(i>>j&1) s++,a[++pos]=1;
else a[++pos]=0; //保留当前棋的局面映 射到1--25 之后判断再转成二维然后判断
}
if(s!=13) continue;
check();
}
cout<<ans;
return 0;
}
//dfs写法 改了一次 能想出来顺序就简单想不出来搜索顺序就难
#include<bits/stdc++.h>
using namespace std;
const int N=1010,M=N*N;
int g[10][10];//1白 0黑色
int ans=0;
void check()
{
int pos=0;
int s1=0,s2=0,s3=0,s4=0;//这里求只要一条直线上的值是0|1代表一方获胜 s1代表行s2代表列 s3s4对角
for(int i=1;i<=5;i++)
{
s1=0,s2=0;
for(int j=1;j<=5;j++)
{
s1+=g[i][j],s2+=g[j][i];
if(i==j) s3+=g[i][j];
if(i+j==6) s4+=g[i][j];//反对角上 下标和是6
}
if(s1==0||s1==5||s2==0||s2==5) return;//不是平局
}
if(s3==0||s3==5||s4==0||s4==5) return;//不是平局
ans++;//平局了
}
void dfs(int x,int y,int k)//第几行吗
{
//if(x==4&&y==4)
if(k==13)
{
check();
return;
}
if(x>=6||y>=6) return;
g[x][y]=1;//最多下棋13次哦 超过无效
if(y+1==6)
dfs(x+1,1,k+1);
else dfs(x,y+1,k+1);
g[x][y]=0;//默认黑棋把
if(y+1==6)
dfs(x+1,1,k);
else dfs(x,y+1,k);
}
int main()
{
dfs(1,1,0);//00 --44 5 5棋盘
cout<<ans;
return 0;
}