第一场排位赛 G题 BoardGame
2015Tishreen- Board Game
以本题为例总结dfs
核心代码
//这里容易出错的点:dfs返回的位置是 [0,n)可以看成在n的位置返回
void dfs(int x,int y......)
{
if(判断条件+边界)
{
//back
}
for(循环)
{
if(标记)
//标记
//下一个步骤
//取消标记
}
//列举完所有情况,返回
}
上代码
对二位数组顺序遍历的小技巧:step从[0,n)进行输入,step/column 为列号 step%raw 为 横号
这题变式在于我们只需要找到一个解,并且在最终返回的有两种情况:满足,不满足,所以采用bool dfs的策略,若成功直接返回到步骤一然后退出循环,若不成功,返回上一层继续进行循环
很巧妙的实现回溯!
#include
using namespace std;
int a[20][20];
int vis[20];
bool is_ok()
{
int t[8]={0};
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
t[i]+=a[i][j];
t[j+4]+=a[i][j];
}
}
for(int i=1;i<8;i++)
{
if(t[i]!=t[i-1])
{
return 0;
}
}
return 1;
}
bool dfs(int step)
{
if(step==16)
{
if(is_ok())
{
return 1;
} else
{
return 0;
}
}else
{
if(a[step/4][step%4]==-1)
{
for(int i=1;i<=16;i++)
{
if(!vis[i])
{
vis[i]=1;
a[step/4][step%4]=i;
if(dfs(step+1)) return 1;
vis[i]=0;
a[step/4][step%4]=-1;
}
}
}else
{
if(dfs(step+1)) return 1;
}
}
return 0; //为什么这里要return 0
}
void solve(int k)
{
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
cin>>a[i][j];
if(a[i][j]!=-1)
{
vis[a[i][j]]=1;
}
}
}
dfs(0);
cout<<"Case "<>kase;
for(int i=1;i<=kase;i++)
{
memset(vis,0,sizeof vis);
solve(i);
if(i!=kase)
{
cout<
补题:8皇后 深化 dfs