您的位置:首页 > 其它

【九度OJ】题目1204:农夫、羊、菜和狼的故事 -----------状态压缩+搜索

2015-09-24 16:00 459 查看
题目描述:
有一个农夫带一只羊、一筐菜和一只狼过河.
果没有农夫看管,则狼要吃羊,羊要吃菜.
但是船很小,只够农夫带一样东西过河。
问农夫该如何解此难题?

输入:
题目没有任何输入。

输出:
题目可能有种解决方法,求出步骤最少的解决方法,
按顺序输出农夫想把羊、菜、狼全部运过河需要哪几个步骤。
如果需要将羊带过河去则输出“sheep_go”。
如果需要将羊带回来则输出“sheep_come”。
如果需要将菜带过河去则输出“vegetable_go”。
如果需要将菜带回来则输出“vegetable_come”。
如果需要将狼带过河去则输出“wolf_go”。
如果需要将狼带回来则输出“wolf_come”。
如果需要空手返回则输出“nothing_come”。
如果需要空手过河则输出“nothing_go”。
每输出一种方案,输出一行“succeed”。

样例输入:

样例输出:

提示:
题目可能有多组解决方法,每种方法输出后要再空一行。
一种方法中的多句话,每句话占一行。

来源:2008年华中科技大学计算机保研机试真题

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>

using namespace std;

typedef long long ll;

queue<pair<int,int> > q;
int pre[20],ans[20];
bool vis[20];

bool check(int x){
if((((x>>0)&1)^((x>>2)&1))==0 && (((x>>3)&1)^((x>>2)&1))==1)
return true;
if((((x>>1)&1)^((x>>2)&1))==0 && (((x>>3)&1)^((x>>2)&1))==1)
return true;
return false;
}

void bfs(){
while(!q.empty())
q.pop();
int st = 0;
for(int i=0;i<4;i++)
st |= (1<<i);
pre[st] = -1;
vis[st] = true;
int cnt = 0;
q.push(make_pair(st,cnt));
while(!q.empty()){
pair<int,int> cur = q.front();
q.pop();
// cout<<"test:"<<cur.first<<' '<<cur.second<<endl;
if(cur.first==0)
{
int c = 0;
ans[c++] = cur.first;
for(int i=pre[cur.first];i!=-1;i=pre[i]){
ans[c++] = i;
}
//            for(int i=0;i<c;i++)
//                cout<<ans[i]<<' ';
//            cout<<endl;
for(int j=c-1;j>0;j--){  //j大是前面的状态
int a = ans[j]^ans[j-1];
if(a&(1<<3)){
if(a&(1<<2)){
if((ans[j-1]&(1<<3)) && (ans[j-1]&(1<<2)))
printf("sheep_come\n");
else{
printf("sheep_go\n");
}
}
else if(a&(1<<1)){
if((ans[j-1]&(1<<3)) && (ans[j-1]&(1<<1)))
printf("vegetable_come\n");
else{
printf("vegetable_go\n");
}
}
else if(a&(1<<0)){
if((ans[j-1]&(1<<3)) && (ans[j-1]&(1<<0)))
printf("wolf_come\n");
else{
printf("wolf_go\n");
}
}
else{
if(ans[j-1]&(1<<3)){
printf("nothing_come\n");
}
else{
printf("nothing_go\n");
}
}
}
}
printf("succeed\n");
return;
}
int x;
x = (cur.first^(1<<3));

if(!check(x) && !vis[x]){
q.push(make_pair(x,cur.second+1));
vis[x] = true;
pre[x] = cur.first;
}

for(int i=0;i<3;i++){
if(~((cur.first&(1<<i))^(cur.first&(1<<3))))
x = ((cur.first^(1<<i))^(1<<3));
if(check(x)) continue;
if(vis[x]) continue;
q.push(make_pair(x,cur.second+1));
vis[x] = true;
pre[x] = cur.first;
}
}
}

int main()
{
bfs();
return 0;
}


View Code

  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: