农夫过河问题
深搜
1.定义搜索空间与搜索状态
状压 0-15
搜索状态转移用异或实现
2.考虑什么时候判断状态非法
很显然是在过河之后看河岸上有没有非法状态
那么可以在到岸时候看吗,并不好,因为不是狼看见羊就吃 羊看见草就吃
所以应该是离开岸边时候判断。
3.状态终止
15
#include<cstdio>
#include<cstdlib>
#include<iostream>
using namespace std;
int crossing=8;
int anss[100];
int success=0;
int tr[100];
int num;
bool check(int x){
int a1=1;
int a2=2;
int a3=4;
int a4=8;
int b1,b2,b3,b4;
if(x&a1) b1=1;else b1=0;
if(x&a2) b2=1;else b2=0;
if(x&a3) b3=1;else b3=0;
if(x&a4) b4=1;else b4=0;
if((b1==b2&&b1!=b4)||(b2==b3&&b3!=b4)) return false;
else return true;
}
void print(int x){
printf("%d %d %d %d\n",(x&8)>0,(x&4)>0,(x&2)>0,(x&1)>0);
}
void dfs(int x,int t){
//printf("%d %d\n",x,t);
//print(x);
if(x==15) {
success=1;
num=t;
anss[num]=x;
return ;
}
if(tr[x]) return ;
tr[x]++;
int inver=1;
int tt;
int qq;
for(int i=1;i<=3;i++)
{
if(((1<<(i-1))&x)>0) tt=1;
else tt=0;
if(((1<<3)&x)>0) qq=1;
else qq=0;
if(tt==qq){//判断能否带
if(tr[(x^crossing)^inver]==0)
{
if(check(x^crossing^inver)) {
dfs((x^crossing)^inver,t+1);} //带一个过去
if(success) {
anss[t]=x;
return ;
}
}
}
inver=inver*2;
}
if(tr[x^crossing]==0) {
if(check(x^crossing)) dfs((x^crossing),t+1); //只自己回来
if(success) {
anss[t]=x;
return ;
}
}
}
int main(){
//起点 0 0 0 0 河岸0
//终点 1 1 1 1 河岸1
// 农夫 狼 羊 草
dfs(0,0); //从0开始搜索
for(int i=0;i<=num;i++){
print(anss[i]); //输出
}
return 0;
}