题目没有任何输入。
题目可能有多种解决方法,请输出步骤最少的任意一种解决方法,
按顺序输出农夫想把羊、菜、狼全部运过河需要哪几个步骤。
如果需要将羊带过河去则输出一行“sheep_go”。
如果需要将羊带回来则输出一行“sheep_come”。
如果需要将菜带过河去则输出一行“vegetable_go”。
如果需要将菜带回来则输出一行“vegetable_come”。
如果需要将狼带过河去则输出一行“wolf_go”。
如果需要将狼带回来则输出一行“wolf_come”。
如果需要空手返回则输出一行“nothing_come”。
如果需要空手过河则输出一行“nothing_go”。
输出任意一种可行的最简方案后,请在最后输出一行“succeed”。
无
按题目要求进行输出即可。
//明显要用到回溯法
#include<stdio.h>
#include<string.h>
typedef struct record{
int type; //sheep|vegetable|wolf|nothing
int dir; //come|go
}Rec;
char state[5]; //代表🐏🐺菜人的状态
Rec list[20];
int count;
int Judge(int x,int direct){//其实可以用map来做,可以很方便的去重
if(strcmp(state,"0111")==0&&x!=3) //防止无限循环
return 0;
if(count!=0&&x==list[count-1].type)//防止无限循环,例如第一次把羊带过去第二次又带回来
return 0;
if(x==3)//nothing
{
if(state[0]==state[1]||state[0]==state[2])
return 0;
return 1;
}
if(state[x]!=state[3])//想要带的和农夫根本不在一边
return 0;
else {
char tmp[5];
strcpy(tmp,state);
tmp[x]='1'-tmp[x]+'0';
tmp[3]='1'-tmp[3]+'0';
if((tmp[0]==tmp[1]||tmp[0]==tmp[2])&&tmp[0]!=tmp[3])
return 0;
return 1;
}
}
void dfs(char * state,int direct){
if(strcmp(state,"1111")==0)
{
for(int i=0;i<count;i++){
switch(list[i].type){
case 0:printf("sheep_");break;
case 1:printf("wolf_");break;
case 2:printf("vegetable_");break;
case 3:printf("nothing_");break;
}
switch(list[i].dir){
case 0:printf("go\n");break;
case 1:printf("come\n");break;
}
}
printf("succeed\n");
return;
}
for(int i=3;i>=0;i--){//代表四个type,每次都从什么都不带开始遍历。
if(Judge(i,direct)){
char tmp = state[i];
list[count].type=i;//记录该操作
list[count].dir=direct;
count++;
state[i]=state[3]=1-direct+'0';//更改状态
dfs(state,1-direct);
state[i]=state[3]=tmp;//回溯
count--;
}
}
}
int main(){
strcpy(state,"0000");
count = 0;
dfs(state,0);
}
#include <stdio.h>
#include <stdlib.h>
//农夫过河问题,用1111的二进制分别代表河的一岸的农夫、狼、羊、菜,假如农夫带狼过河则1111变为0011
//总共有16种状态,每次过河的操作(8种操作)都会变成另外一个状态,直到得到0000,
//可以得到一个状态树,保存满足条件的路径
//不满足题目要求的状态有0111,0110,0011,1000,1001,1100
//建立一个当前搜索队列,保存遍历的状态,出现重复的状态则不进行这次变化(避免死循环),若队尾出现0,退出搜索
#define nothing_go -8
#define nothing_come 8
#define wolf_go -12
#define wolf_come 12
#define vegetable_go -9
#define vegetable_come 9
#define sheep_go -10
#define sheep_come 10
int Move[8] = {-12, -10, -9, -8, 8, 9, 10, 12};
typedef struct Results{
int r[100];
int length;
}Results;
Results Result[10];
int re_num=0;
int queue[100],length=0; //队列长度
int judge(int b, int m){//判断此次变化是否满足过河要求
int i, a = b + m;
if(m>0&&(m-8)&b>0)//如果是回来,那么你带的物品一定是这边没有的
//(m-8)&b==0表示带来的物品这边没有,防止羊被分解成菜带回来了
return 0;
if(m<0&&(abs(m)-8)&b==0)//带过去的物品一定要存在
return 0;
//判断过河后的状态是否满足条件或者出现过
if(a>15||a<0)
return 0;
if(a==12||a==9||a==8||a==7||a==6||a==3)
return 0;
for(i=0;i<length;i++)
if(a==queue[i])
return 0;
return 1;
}
//8种变化分别为
int Rivercross(int a){//生成状态树
int i;
queue[length]=a;
if(a==0){//过河成功,保存队列信息
for(i=0;i<length;i++){
Result[re_num].r[i]=queue[i];
}
Result[re_num].length=length+1;
re_num++;
return 1;
}
for(i = 0; i < 8; ++i) {
++length;
if(judge(a, Move[i]))
Rivercross(a + Move[i]);
--length;
}
}
void myprint(int index){//格式化输出
int i;
for(i=0;i<Result[index].length-1;i++){
switch(Result[index].r[i+1]-Result[index].r[i]){
case -8:printf("nothing_go\n");break;
case 8:printf("nothing_come\n");break;
case -12:printf("wolf_go\n");break;
case 12:printf("wolf_come\n");break;
case -9:printf("vegetable_go\n");break;
case 9:printf("vegetable_come\n");break;
case -10:printf("sheep_go\n");break;
case 10:printf("sheep_come\n");break;
}
}
}
int main()
{
int i,min_index=0;
Rivercross(15);
for(i=1;i<re_num;i++)//寻找最短路径序号
if(Result[i].length<Result[min_index].length)
min_index=i;
for(i=0;i<re_num;i++){//等于最短路径长度的结果输出
if(Result[i].length == Result[min_index].length){
myprint(i);
printf("succeed\n\n");
}
}
}
//最近刚学的算法,这属于用的回溯吗? //感觉题目出的不严谨,因为最后输出的方案应该是有两个,第三步应该可以菜过河,也可以狼过河 //所以我的输出是两个,然而题目的答案只输出了一个😓😓😓。 #include<iostream> #include<vector> using namespace std; typedef struct Record{ int passage;//0 vegetables ; 1 sheep ; 2 wolf ;3 nothing int ifgo; //1 go ; 0 come Record(int a,int b):passage(a),ifgo(b){} }Record; vector<vector<Record> > result; //存储可行的乘船经历 vector<Record> rec; //记录当前状态 int goline[3]={1,1,1}; //等待过河的队伍的存在状态,1代表在,0代表不在(即在对面),3代表在渡船,下标0代表蔬菜,1代表羊,2代表狼 void goRiver(int lastPass); void comeRiver(int lastPass); bool ifFeasible(){ if(goline[2]==goline[1]||goline[1]==goline[0]) return false; return true; } bool ifEnd(){ for(int i=0;i<3;i++){ if(goline[i]!=0) return false; } return true; } void goRiver(int lastPass){ for(int i=0;i<3;i++){ if(goline[i]&&goline[i]!=lastPass){ goline[i]=3; if(ifFeasible()){ goline[i]=0; Record q(i,1); rec.push_back(q); comeRiver(i); goline[i]=1; rec.pop_back(); }else{ goline[i]=1; } } } return; } void comeRiver(int lastPass){ if(ifEnd()){ result.push_back(rec); return; } if(ifFeasible()){ Record q(3,0); rec.push_back(q); lastPass=3; goRiver(lastPass); } for(int i=0;i<3;i++){ if(goline[i]==0&&goline[i]!=lastPass){ goline[i]=3; if(ifFeasible()){ goline[i]=1; Record q(i,0); rec.push_back(q); goRiver(i); goline[i]=0; rec.pop_back(); }else{ goline[i]=0; } } } return; } int minRecord(){ int minnum=0; for(int i=0;i<result.size();i++){ if(result[i].size()<minnum) minnum=result[i].size(); } return minnum; } void printProcess(int n){ for(int i=0;i<result[n].size();i++){ string a,b; switch(result[n].at(i).passage){ case 0: a="vegetable_"; break; case 1: a="sheep_"; break; case 2: a="wolf_"; break; case 3: a="nothing_"; break; } switch(result[n].at(i).ifgo){ case 0: b="come"; break; case 1: b="go"; break; } cout<<a<<b<<endl; } } int main(){ goRiver(-1); int minnum=minRecord(); for(int i=0;i<result.size();i++){ if(result[i].si***num){ printProcess(i); cout<<"succeed"<<endl; } } }
#include<iostream>
#include <string>
#include <type_traits>
#include <vector>
#include <algorithm>
using namespace std;
bool danger(int& f, int& s, int& v, int& w);
bool visited(vector<string>& state, string s);
string build(int f, int s, int v, int w);
bool test(int& f, int& s, int& v, int& w, vector<string>& state);
bool cheak(int f, int s, int v, int w, vector<string>& state);
bool danger(int& f, int& s, int& v,
int& w) { //检测是否处于危险状态。
if ((s == v && f != s) || (w == s && f != w)) return true;
else return false;
}
bool visited(vector<string>& state,
string s) { //检测该状态是否已经访问过。
if (find(state.begin(), state.end(), s) != state.end()) {
return true;
} //访问过该状态则返回真
else {
state.push_back(
s); //未访问过时则将此状态记录,并访问该状态。
return false;
}
}
string build(int f, int s, int v,
int w) { //描述当前状态,生成状态字符串。
string temp;
temp.append(to_string(f));
temp.append(to_string(s));
temp.append(to_string(v));
temp.append(to_string(w));
return temp;
}
bool cheak(int f, int s, int v, int w,
vector<string>& state) { //根据当前环境与状态队列来判断当前状态是否访问过。
string str = build(f, s, v, w);
// for (auto it = state.begin(); it != state.end(); it++) cout << *it << ' ';
// cout << endl;
return visited(state, str);
}
bool test(int& f, int& s, int& v, int& w, vector<string>& state) {
if (f & s & v & w) {
cout << "succeed" <<
endl; //找到解时输出,并返回真值以结束查找。
return true;
} else {
if (f == 0) {
f = 1;
if (danger(f, s, v, w) || cheak(f, s, v, w, state)) {
f = 0; //新状态危险或已访问时,进行回溯。
} else {
cout << "nothing_go" << endl;
if (test(f, s, v, w, state)) return
true; //若找到解,则会逐层返回真值以退出递归。
f = 0; //上一条路径无法找到解时,同样进行回溯。
}
if (s == f) {
f = 1;
s = 1;
if (danger(f, s, v, w) || cheak(f, s, v, w, state)) {
f = 0;
s = 0;
} else {
cout << "sheep_go" << endl;
if (test(f, s, v, w, state)) return true;
f = 0;
s = 0;
}
}
if (v == f) {
f = 1;
v = 1;
if (danger(f, s, v, w) || cheak(f, s, v, w, state)) {
f = 0;
v = 0;
} else {
cout << "vegetable_go" << endl;
if (test(f, s, v, w, state)) return true;
f = 0;
v = 0;
}
}
if (w == f) {
f = 1;
w = 1;
if (danger(f, s, v, w) || cheak(f, s, v, w, state)) {
f = 0;
w = 0;
} else {
cout << "wolf_go" << endl;
if (test(f, s, v, w, state)) return true;
f = 0;
w = 0;
}
}
} else {
f = 0;
if (danger(f, s, v, w) || cheak(f, s, v, w, state)) {
f = 1;
} else {
cout << "nothing_come" << endl;
if (test(f, s, v, w, state)) return true;
f = 1;
}
if (s == f) {
f = 0;
s = 0;
if (danger(f, s, v, w) || cheak(f, s, v, w, state)) {
f = 1;
s = 1;
} else {
cout << "sheep_come" << endl;
if (test(f, s, v, w, state)) return true;
f = 1;
s = 1;
}
}
if (v == f) {
f = 0;
v = 0;
if (danger(f, s, v, w) || cheak(f, s, v, w, state)) {
f = 1;
v = 1;
} else {
cout << "vegetable_come" << endl;
if (test(f, s, v, w, state)) return true;
f = 1;
v = 1;
}
}
if (w == f) {
f = 0;
w = 0;
if (danger(f, s, v, w) || cheak(f, s, v, w, state)) {
f = 1;
w = 1;
} else {
cout << "wolf_come" << endl;
if (test(f, s, v, w, state)) return true;
f = 1;
w = 1;
}
}
}
return false; //未找到解时返回假值以进行回溯。
}
}
int main() {
int farm = 0, sheep = 0, veg = 0, wolf = 0;
vector<string> state;
string s;
s = build(farm, sheep, veg, wolf); // 初始化状态队列。
state.push_back(s);
test(farm, sheep, veg, wolf, state);
return 0;
} #include <iostream>
#include <stdio.h>
using namespace std;
/*
用8位bit来表示两岸的状态,假设是从右岸到左岸, 右岸和左岸分别有四个状态,即 菜,羊,狼,农夫, 1表示在此岸,0表示不在此岸
初始时,为 0b0000 1111, 表示 菜,羊,狼,农夫全部在右岸。 有两岸,4种move,总共8种,如0b00000011,表示狼和农夫一起从右岸走, 0b00110000,表示狼和农夫一起从左岸走。
1.判断是否全到左岸,是则退出递归并输出相应的move。否,从四种move中选择一种,进入2
2.判断此岸是否有条件进行move,如此岸有狼才能wolf_go或wolf_come。若是,进入3,否,返回1
3.判断move与上次move是否对应,如 上次nothing_go,此次不能再次nothing_come。 若是,返回1,若否,进入4
4.渡河,两岸的状态改变,判断 离开的那一岸,是否会出现狼吃羊,羊吃菜的现象,若是,返回1,若否,进入5
5.更新两岸状态,回到1继续判断
中间遇到一个bug,也就是move_flag的顺序改变,第一个不是nothing_come和nothing_go,会陷入无限循环:
sheep_go, nothing_come, wolf_go, sheep_come, vegetable_go。 此时羊在右岸,农夫,狼和菜在左岸。
如果下一步选择 wolf_come, 那么就会出现死循环,而nothing_come则就能正确得出解。
改变move_flag内的顺序,就会出现bug
u8 move_flag[2][4] = { {WOLF_GO, SHEEP_GO, VEGETABLE_GO, NOTHING_GO},
{WOLF_COME, SHEEP_COME, VEGETABLE_COME, NOTHING_COME}};
将nothing_go,nothing_come放在第一个位置,隐含左岸优先级比右岸高,否则会出现两岸是等同地位,跳不出循环
*/
#define WOLF_EAT_SHEEP_RIGHT 0x06 // 农夫离开右岸,出现狼吃羊
#define WOLF_EAT_SHEEP_LEFT 0x60 // 左岸,狼吃羊
#define SHEEP_EAT_VEG_RIGHT 0x0c // 右岸,羊吃菜
#define SHEEP_EAT_VEG_LEFT 0xc0 // 左岸,羊吃菜
#define RIGHT 0
#define LEFT 1
#define MAX_SIZE 300
#define NOTHING_GO 0b00000001
#define NOTHING_COME 0b00010000
#define WOLF_GO 0b00000011
#define WOLF_COME 0b00110000
#define SHEEP_GO 0b00000101
#define SHEEP_COME 0b01010000
#define VEGETABLE_GO 0b00001001
#define VEGETABLE_COME 0b10010000
typedef unsigned char u8;
string a[MAX_SIZE];
u8 move_flag[2][4] = { {NOTHING_GO, WOLF_GO, SHEEP_GO, VEGETABLE_GO},
{NOTHING_COME, WOLF_COME, SHEEP_COME, VEGETABLE_COME}};
void init() {
a[NOTHING_GO] = "nothing_go";
a[WOLF_GO] = "wolf_go";
a[SHEEP_GO] = "sheep_go";
a[VEGETABLE_GO] = "vegetable_go";
a[NOTHING_COME] = "nothing_come";
a[WOLF_COME] = "wolf_come";
a[SHEEP_COME] = "sheep_come";
a[VEGETABLE_COME] = "vegetable_come";
}
void cross_river(u8 river_flag, bool &zflag, u8 last_move) {
if ( river_flag == 0b11110000) { // 都到左岸,退出递归
zflag = true;
return ;
}
int this_side = (river_flag & 0x01) == 0x01 ? RIGHT : LEFT;
int that_side = (river_flag & 0x01) == 0x01 ? LEFT : RIGHT;
for (int i = 0; i < 4; i++) {
if ((move_flag[this_side][i] & river_flag) != move_flag[this_side][i] ) { // 判断this_side有对应的事物才能带到对面去,也就能执行相应的move
continue;
}
if (last_move == move_flag[that_side][i]) { // 上一次和此次的move应该不一致,否则此次move是无意义的
continue;
}
u8 rf_temp = river_flag - move_flag[this_side][i] | move_flag[that_side][i]; // 渡河,到达了对岸,此时两岸的状态
// 离开了右岸,判断右岸是否出现了狼吃羊,或羊吃菜的现象
if (this_side == RIGHT && ((rf_temp & WOLF_EAT_SHEEP_RIGHT) == WOLF_EAT_SHEEP_RIGHT || (rf_temp & SHEEP_EAT_VEG_RIGHT) == SHEEP_EAT_VEG_RIGHT)) {
continue;
}
// 离开了左岸,判断左岸是否出现了狼吃羊,或羊吃菜的现象
if (this_side == LEFT && ((rf_temp & WOLF_EAT_SHEEP_LEFT) == WOLF_EAT_SHEEP_LEFT || (rf_temp & SHEEP_EAT_VEG_LEFT) == SHEEP_EAT_VEG_LEFT) ) {
continue;
}
// 上述条件都通过,此次move有意义,进入下一次抉择
cross_river(rf_temp, zflag, move_flag[this_side][i]);
if (zflag) {
cout << a[move_flag[this_side][i]] << endl;
return;
}
}
}
int main() {
u8 river_flag = 0x0f; // 0b 0000 1111, 低四位是右边的河岸,从右到左,1表示 农夫,狼,羊,菜
bool zflag = false;
init();
cross_river(river_flag, zflag, 0x00);
if (zflag) {
cout << "succeed" << endl;
}
return 0;
}
// 64 位输出请用 printf("%lld") //羊go 无come 菜go 羊come 狼go 无come 羊go,前提条件羊必须自己在一边
#include<stdio.h>
int main()
{
printf("sheep_go\n");
printf("nothing_come\n");
printf("vegetable_go\n");
printf("sheep_come\n");
printf("wolf_go\n");
printf("nothing_come\n");
printf("sheep_go\n");
printf("succeed\n");
} #include <stdio.h>
#include <queue>
using namespace std;
queue<int> S;
int visit[20];//用来保存当前状态的前一状态
int a[4]={8,12,10,9};//用来表示4种状态转换操作
bool judge(int x)
{//用来判断是否为合法状态
if(x>=5&&x<=10)
return false;
else if(x>15 || x<0)
return false;
else if(visit[x]!=-1)
return false;
else
return true;
}
void BFS()
{
int current=S.front();
S.pop();
for(int i=0;i<4;i++ )
{
int next=a[i]^current;
if(judge(next))
{
S.push(next);
visit[next]=current;
if(next == 15)
return;
}
}
BFS();
}
void myprint(int a1,int a2)
{
switch(a2-a1)
{
case -8: printf("nothing_come\n");break;
case -12: printf("sheep_come\n");break;
case -10: printf("vegetable_come\n");break;
case -9: printf("wolf_come\n");break;
case 8: printf("nothing_go\n");break;
case 12: printf("sheep_go\n");break;
case 10: printf("vegetable_go\n");break;
case 9: printf("wolf_go\n");break;
}
}
int main()
{
int state =0;
for(int i=0;i<16;i++)
visit[i]=-1;
S.push(state);
visit[state]=-2;
BFS();
int x=15;
int a[20];//根据visit数组来获得路径顺序,即状态序列
int idx=0;
while(x!=-2)
{
a[idx++]=x;
x=visit[x];
}
for(int i=idx-1;i>0;i--)
{//根据a数组即状态序列的变换打印状态转换过程
myprint(a[i],a[i-1]);
}
printf("succeed\n");
return 0;
}
#include <iostream>
#include <vector>
#include <queue>
#include <map>
using namespace std;
bool is_visited[2][2][2][2] = { false };
struct State{
int person;
int wolf;
int sheep;
int vegetable;
int path; //记录之前的操作序列,每一位代表一个操作
State(int p,int w,int s,int v, int way):person(p),wolf(w),sheep(s),vegetable(v),path(way){}
};
//(人,狼,羊,菜)四元组,0表示在此岸,1表示在对岸
bool is_valid(int p, int w, int s, int v){
if(w == s && p != w)
return false;
if(s == v && p != s)
return false;
if(p < 0 || w < 0 || s < 0 || v < 0)
return false;
if(p > 1 || w > 1 || s > 1 || v > 1)
return false;
if(p == 0 && w == 0 && s == 0 && v == 0)
return false;
return !is_visited[p][w][s][v];
}
bool operation(int op, State &s){
int np = s.person, nw = s.wolf, ns = s.sheep, nv = s.vegetable;
switch (op){
case 1:
np++;
ns++;
break;
case 2:
np--;
ns--;
break;
case 3:
np++;
nv++;
break;
case 4:
np--;
nv--;
break;
case 5:
np++;
nw++;
break;
case 6:
np--;
nw--;
break;
case 7:
np++;
break;
case 8:
np--;
break;
}
if(is_valid(np, nw, ns, nv)){
s.person = np, s.wolf = nw, s.sheep = ns, s.vegetable = nv;
s.path = s.path * 10 + op;
return true;
}
else
return false;
}
void display(int path){ //输出转移方法
string str = to_string(path);
while(str.size() != 0){
switch (str[0] - '0'){
case 1:
cout<<"sheep_go"<<endl;
break;
case 2:
cout<<"sheep_come"<<endl;
break;
case 3:
cout<<"vegetable_go"<<endl;
break;
case 4:
cout<<"vegetable_come"<<endl;
break;
case 5:
cout<<"wolf_go"<<endl;
break;
case 6:
cout<<"wolf_come"<<endl;
break;
case 7:
cout<<"nothing_go"<<endl;
break;
case 8:
cout<<"nothing_come"<<endl;
break;
}
str.erase(str.begin());
}
}
void bfs(State s){
queue<State> myqueue;
myqueue.push(s);
while(!myqueue.empty()){
State temp = myqueue.front();
myqueue.pop();
if(temp.person == 1 && temp.wolf == 1 && temp.sheep == 1 && temp.vegetable == 1){
display(temp.path);
cout<<"succeed"<<endl;
return ;
}
for(int i = 1; i <= 8; i++){
bool flag = operation(i, temp);
if(flag){
is_visited[temp.person][temp.wolf][temp.sheep][temp.vegetable] = true;
myqueue.push(temp);
}
}
}
}
int main() {
State start(0, 0, 0, 0, 0);
bfs(start);
}
#include <iostream>
#include <string>
#include <queue>
using namespace std;
string map[4] = {"nothing", "vegetable", "sheep", "wolf"};
struct Status {
bool flags[4]; // 下标 1, 2, 3 分别表示蔬菜,羊,狼,下标 0 冗余;false 表示在河这岸,true 表示过河对岸
int step; // 表当前第几步,为偶数时农夫在河这岸,为奇数时农夫过河对岸
string process; // 过河步骤过程
Status(bool f[3], int s, string p) {
flags[0] = false;
for (int i = 1; i <= 3; i++) {
flags[i] = f[i - 1];
}
step = s;
process = p;
}
};
bool Valid(const Status& s) {
bool f = s.step % 2 == 0; // 偶数时农夫在河这岸,就检查河对岸;反之亦然
// if (s.flags[1] == f && s.flags[2] == f) { // 蔬菜和羊在一起
// return false;
// }
// if (s.flags[2] == f && s.flags[3] == f) { // 羊和狼在一起
// return false;
// }
// return true;
return !(s.flags[1] == f && s.flags[2] == f || s.flags[2] == f && s.flags[3] == f);
}
bool Succeed(const Status& s) {
return s.flags[1] && s.flags[2] && s.flags[3]; // 蔬菜,羊和狼都到达河对岸
}
string BFS() {
queue<Status> q;
bool initFlags[3] = {false, false, false};
q.push(Status(initFlags, 0, "")); // 压入初始状态
while (!q.empty()) {
Status cur = q.front();
q.pop();
if (Succeed(cur)) { // 找到了目标状态
return cur.process;
}
for (int i = 0; i <= 3; i++) {
Status next = cur; // 每轮循环都创建一个新的 next,避免各个 next 数据互相影响
next.step ++;
next.process += (i + '0'); // 当前步骤带什么过河,0 表示什么都不带
bool flag = next.step % 2 == 1;
if (i != 0 && !next.flags[i] == flag) { // 如果当前步骤农夫要过河对岸,则只能带目前在河这岸的;反之亦然
next.flags[i] = flag;
}
if (Valid(next)) {
q.push(next);
}
}
}
}
void PrintProcess(string process) {
for (int i = 0; i < process.size(); i++) {
if (i % 2) {
cout << map[process[i] - '0'] << "_come" << endl;
} else {
cout << map[process[i] - '0'] << "_go" << endl;
}
}
cout << "succeed" << endl;
}
int main() {
string process = BFS();
PrintProcess(process);
return 0;
} #include <iostream>
#include <string.h>
using namespace std;
void goahead();
void print(int a[],int n);
const int maxin=10;
int arr[2][3];
int step[maxin];
int final_step[maxin];
int len=0,num=0;
int cnt=-1;
bool judge_OK(int a[])
{
if(a[0]&&a[1])
return false;
else if(a[1]&&a[2])
return false;
else return true;
}
void goback()
{
if(arr[1][0]&&arr[1][1]&&arr[1][2])
{
if(!num||num>len)
{
num=len;
for(int i=0;i<num;i++)
final_step[i]=step[i];
}
return;
}
int pre=cnt;
for(int i=0;i<4;i++)
{
if(arr[1][0]&&arr[1][2]) i=3;
if(i!=cnt&&arr[1][i]&&i!=3)
{
arr[1][i]=0;
if(!judge_OK(arr[1])) arr[1][i]=1;
else
{
arr[0][i]=1;
cnt=i;
step[len++]=i;
goahead();
len--;
cnt=pre;
arr[0][i]=0;
arr[1][i]=1;
}
}
else if(i==3)
{
if(!judge_OK(arr[1])) break;
else{
cnt=-1;
step[len++]=i;
goahead();
len--;
cnt=pre;
}
}
}
}
void goahead()
{
for(int i=0;i<4;i++)
{
int pre=cnt;
if(i!=cnt&&i!=3&&arr[0][i])
{
arr[0][i]=0;
if(!judge_OK(arr[0])) arr[0][i]=1;
else
{
arr[1][i]=1;
cnt=i;
step[len++]=i;
goback();
len--;
cnt=pre;
arr[1][i]=0;
arr[0][i]=1;
}
}
else if(i==3&&!arr[0][0]&&!arr[0][1]&&!arr[0][2])
{
if(!judge_OK(arr[0])) break;
else{
cnt=-1;
step[len++]=i;
goback();
len--;
cnt=pre;
}
}
}
}
void print(int a[],int n)
{
for(int i=0;i<n;i++)
{
if(i%2)
{
switch(a[i])
{
case 0:cout<<"wolf_come"<<endl;
break;
case 1:cout<<"sheep_come"<<endl;
break;
case 2:cout<<"vegetable_come"<<endl;
break;
case 3:cout<<"nothing_come"<<endl;
break;
default:break;
}
}
else
{
switch(a[i])
{
case 0:cout<<"wolf_go"<<endl;
break;
case 1:cout<<"sheep_go"<<endl;
break;
case 2:cout<<"vegetable_go"<<endl;
break;
case 3:cout<<"nothing_go"<<endl;
break;
default:break;
}
}
}
cout<<"succeed"<<endl;
}
int main()
{
for(int i=0;i<3;i++)
{
arr[0][i]=1; //0表示狼,1表示羊,2表示菜,3表示空手;
arr[1][i]=0;
}
goahead();
print(final_step,num);
}
#include <iostream>
#include <vector>
#include <string>
#define GAME_WIN 1
#define GAME_OVER -1
#define GAME_NORMAL 0
#define DIR_GO 0
#define DIR_COME 1
typedef union{
uint8_t data;
struct{
uint8_t sheep:1;
uint8_t vegetable:1;
uint8_t wolf:1;
uint8_t farmer:1;
}all;
}Game;
typedef struct{
uint8_t data;
int dir;
int status;
std::string detail;
}Step;
int check(Game &g) {
switch(g.data) {
case 0b0000:
return GAME_WIN;
case 0b0111:
case 0b0101:
case 0b0011:
case 0b1000:
case 0b1010:
case 0b1100:
return GAME_OVER;
default:
return GAME_NORMAL;
}
}
int move_sheep(Game &g) {
if(g.all.farmer == g.all.sheep) {
g.data ^= 0b1001;
return g.all.farmer; // 0 = go, 1 = come
}
return GAME_OVER; // bad move = game over
}
int move_vegetable(Game &g) {
if(g.all.farmer == g.all.vegetable) {
g.data ^= 0b1010;
return g.all.farmer;
}
return GAME_OVER;
}
int move_wolf(Game &g) {
if(g.all.farmer == g.all.wolf) {
g.data ^= 0b1100;
return g.all.farmer;
}
return GAME_OVER;
}
int move_farmer(Game &g) {
g.data ^= 0b1000;
return g.all.farmer; // 0 = go, 1 = come
}
int next_move(Game &g, int type) {
switch(type) {
case 0:
return move_sheep(g);
case 1:
return move_vegetable(g);
case 2:
return move_wolf(g);
case 3:
return move_farmer(g);
default:
return GAME_OVER;
}
}
std::vector<Step> history;
int dir = 0, status = 0;
void dfs(Game &g) {
// game over -> return
if(dir == GAME_OVER || status == GAME_OVER) {
return;
}
// win -> return
if(status == GAME_WIN) {
for(int i = 1; i < history.size(); ++i) { // skip the initial state
std::cout << history[i].detail << std::endl;
}
std::cout << "succeed" << std::endl;
return;
}
// check loop -> return
for(int i = 0; i < history.size() - 1; ++i) {
if(history[i].data == g.data)
return;
}
for(int i = 0; i < 4; ++i) {
// move and check
dir = next_move(g, i);
status = check(g);
// save history
Step s;
s.data = g.data;
s.dir = dir;
s.status = status;
switch(i) {
case 0:
s.detail = "sheep_";
break;
case 1:
s.detail = "vegetable_";
break;
case 2:
s.detail = "wolf_";
break;
case 3:
s.detail = "nothing_";
break;
default:
break;
}
s.detail.append(s.dir == DIR_GO ? "go" : "come");
history.push_back(s);
// next step
dfs(g);
// backtrack
history.pop_back();
g.data = history.back().data;
dir = history.back().dir;
status = history.back().status;
}
}
int main() {
Game game;
game.data = 0x0F; // game init
Step s;
s.data=0x0f;
history.push_back(s); // history init
dfs(game);
return 0;
}
import java.util.*;
/**0:农夫, 1:羊, 2:菜, 3:狼*/
public class Main{
private static int[] status = {0, 0, 0, 0};
private static boolean flag;
private static Stack<String> q = new Stack<>();
private static HashMap<String, Boolean> isExist = new HashMap<>();
private static String[] info = {"nothing_", "sheep_", "vegetable_", "wolf_"};
private static String[] way = {"come", "go"};
public static String state(){
StringBuilder sb = new StringBuilder();
for(int i = 0; i < 4; i++)
sb.append(status[i]);
return new String(sb);
}
public static boolean Judge(){
if(status[1] == status[2] && status[1] != status[0])
return false;
if(status[1] == status[3] && status[1] != status[0])
return false;
return true;
}
public static void dfs(int x){
if(status[0] == 1 && status[1] == 1 && status[2] == 1 && status[3] == 1){
flag = true;
for(String str : q)
System.out.println(str);
System.out.println("succeed");
return;
}
for(int i = 0; i < 4; i++){
if(status[i] == x)
continue;
status[i] = x;
status[0] = x;
String curState = state();
if(isExist.containsKey(curState)){
status[i] = 1 - x;
status[0] = 1 - x;
continue;
}
if(Judge()){
q.add(info[i] + way[x]);
isExist.put(curState, true);
dfs(1 - x);
if(flag)
return;
q.pop();
}
else{
status[i] = 1 - x;
status[0] = 1 - x;
}
}
}
public static void main(String[] args){
dfs(1);
}
} #include<stdio.h>
void Print(int x){
switch(x){
case 1: printf("sheep_go\n");break;
case 2: printf("sheep_come\n");break;
case 3: printf("vegetable_go\n");break;
case 4: printf("vegetable_come\n");break;
case 5: printf("wolf_go\n");break;
case 6: printf("wolf_come\n");break;
case 7: printf("nothing_go\n");break;
case 8: printf("nothing_come\n");break;
case 9: printf("succeed\n");break;
default:printf("Error!\n");
}
}
int main(){
Print(1);//农夫带羊过河
Print(8);//农夫自己回去
Print(3);//农夫带菜过河
Print(2);//农夫带羊回去
Print(5);//农夫带狼过河
Print(8);//农夫自己回去
Print(1);//农夫带羊过河
Print(9);//成功
}