人狼羊菜过河

一个人要将一匹狼、一只羊、一筐菜运到河对岸,但是他的船太小了,一次只能带一样过河。当他不在时,狼要吃羊、羊要吃菜。他怎样才能安全地将狼、羊、菜都运过河呢?
在这里插入图片描述Please write a program to find out all the ways to cross the river.

Use four letters to represent the states of man, Wolf, sheep and vegetable respectively:

M means people are there, and. Means people are not there
W means the Wolf is there, and. Means the Wolf is not there
G is for sheep and. Is for sheep
C is for the dish, and. Is for the dish
Use -> to indicate that the ship will go from the left bank to the right bank, use <- to indicate that the ship will go from the right bank to the left bank.

Illustration
If all the vegetables are on the left bank, the state is denoted as

MWGC -> ....

If sheep are transported to the right bank and only wolves and vegetables are left on the left bank, the state is expressed as

.W.C <- M.G.

Input Specification:

The initial state  
Termination status  

Output Specification:

Output all solutions, if any.  
Each solution consists of several lines, each representing a state.  
There is a blank line between the different solutions.  
If there is no solution, None is printed.  

Requirement: Two lines of the same state are not allowed in the output solution.
Sample Input 1:

MWGC -> ....
.... <- MWGC

Sample Output 1:

MWGC -> ....
.W.C <- M.G.
MW.C -> ..G.
...C <- MWG.
M.GC -> .W..
..G. <- MW.C
M.G. -> .W.C
.... <- MWGC

MWGC -> ....
.W.C <- M.G.
MW.C -> ..G.
.W.. <- M.GC
MWG. -> ...C
..G. <- MW.C
M.G. -> .W.C
.... <- MWGC

Sample Input 2:

.W.. <- M.GC
M.GC -> .W..

Sample Output 2:

.W.. <- M.GC
MWG. -> ...C
..G. <- MW.C
M.GC -> .W..

.W.. <- M.GC
MW.C -> ..G.
...C <- MWG.
M.GC -> .W..

Sample Input 3:

MWG. -> ...C
MWG. -> ...C

Sample Output 4:

None

Sample Input 4:

MWG. -> ...C
.WG. -> M..C

Sample Output 4:

None

Note: In order to keep the sequence of output solutions consistent, people are required to explore the following sequence each time they cross the river:

Cross the river directly (without carrying anything)
Take the Wolf across the river
Take the sheep across the river
Take food across the river

/* 人狼羊菜过河 */
/* ATTENTION */
/* This program runs in C++ mode, if this program can't run correctly in your computer, please filling-in this sentence "-std=c++11" in Compiler Settings */

/* Data Structures and Algorithm */
/*
 *	The program algorithm is ergodic exhaustive plus backtracking.
 *	The program identifies each output statement with a number, and every item has two and only two states, so the program tries to solve the labeling program with binary numbers.
 */

#include<stdio.h>
#include<math.h>

#define Radix 16

void Scan();   			 // scan the orginal number and save the destination
void print_Path();	  	 // print the correct path from the first step to the last
void check_Result();	 // there is result or not showed by flag (flag = 0 --> None)

void moving(); 			 // moving objects by using method
int get_Bin(); 			 // translate the Objects array into an binary number, and output in decimal
int get_Bin(int move);	 // get the changing number of the move
int islegalScan();		 // judge it is a legally scan (illegal--0  legal--1)
int check(int Bin);   	 // get the result by checking method (false--0  true--1  correct--2)
int survive(int way);	 // return the remider to show they are in the same state (false--0  true--1)

/* Object Move */
void method0();			 // move  M
void method1();			 // move  M & W
void method2();			 // move  M & G
void method3();			 // move  M & C

/* Stack */
void push(int method);	 // push the method into the stack
void pop();   			 // pop method from the stack


int flag = 0;  					// IOF one --> flag = 0    else --> flag = 1;
int top = -1;					// top of the stack
int stack[Radix];				// the stack of moving
int Objects[4];					// M W G C     0 -- Left   1 -- Right
int checkArray[Radix] = {0};	// pow(2, 4)   0 --> uncollected      1 --> collected
int pathArray[Radix];			// record the path of the orginal to the destination

int original = 15;				// create an immutable primitive variable for multi-mode output
int destination = 15;			// initializing to 15 tends to change it (Minus each of the null -- '.')

//----main--------
int main(void)
{
	Scan();
	
	if(islegalScan())moving();
	
	check_Result();
	
	return 0;
}
//----main--------

void Scan()
{
	int i;
	char ch;
	for(i=0; i<13; i++)
	{
		ch = getchar();
		if(i < 4) {
			if(ch == '.') {
				Objects[i] = 0;
				original -= pow(2, 3-i);
			}
			else Objects[i] = 1;
		}
	}
	
	for(i=0; i<13; i++)
	{
		ch = getchar();
		if(i < 4) {
			if(ch == '.')destination -= pow(2, 3-i);
		}
	}
}

int islegalScan()
{
	// both the original and the destination are the same  or  (the original or the destination) is a wrong state
	if(original == destination || check(original) == 0 || check(destination) == 0)return 0;
	checkArray[original] = 1;
	return 1;
}

int check(int Bin)//false --> 0    true --> 1    correct --> 2
{
	int n = Bin;
	// ATTENTION   the false checking should before the correct checking
	if(n == 3 || n == 6 || n == 7 || n == 8 || n == 9 || n == 12)return 0; // false method
	else if(n == destination)return 2; // correct path
	else return 1; // true
}

int survive(int way)
{
	switch(way) {
		case 0: return 1;break; 							 // M
		case 1: if(Objects[0] == Objects[1])return 1; break; // M & W
		case 2: if(Objects[0] == Objects[2])return 1; break; // M & G
		case 3: if(Objects[0] == Objects[3])return 1; break; // M & C
	}
	return 0;
}

void moving()
{
	int i;
	int check_result = check( get_Bin() );
	if(check_result == 0) { // false method
		checkArray[get_Bin()] = 0;
		pop();
		return;
	}
	if( check_result == 2 ) { // correct method
		int temp = original; // to leave original unchanged, create a new variable
		int change_Bin;
		for(i=0; i<=top; i++)
		{
			pathArray[i] = temp; // store the path in positive order
			change_Bin = get_Bin(stack[i]); // put the changing number of the method into "change_Bin"
			if(temp > 7) { // from Right to Left  --- plus
				temp -= change_Bin;
			}else {
				temp += change_Bin; // from Left to Right  --- minus
			}
		}
		pathArray[i] = temp;
		print_Path(); // print the path
		checkArray[get_Bin()] = 0; // after finish the print, as the "check_result == 0"
		pop(); // ready to next print_Path (if there are diffdrent ways)
		return;
	}
	
	for(i=0; i<4; i++)
	{
		if(survive(i))push(i); // check are they in the same state
		else continue;
		if(checkArray[get_Bin()] == 1) { // have already appeared, false
			pop();
			continue;
		}else {
			checkArray[get_Bin()] = 1; // from 0 to 1, be enclosed
		}
		moving(); // recursion to run through all
	}
	checkArray[get_Bin()] = 0; // this layer traversal is complete, pop out to the next layer
	pop();
}

int get_Bin()// 0000 to 1111 (Binary system return by decimalism)
{
	int result = 0;
	if(Objects[0]) result += 8; // 1...
	if(Objects[1]) result += 4; // .1..
	if(Objects[2]) result += 2; // ..1.
	if(Objects[3]) result += 1; // ...1
	return result;
}

int get_Bin(int move)// result represent the changing number of different methods
{
	int result = 0;
	switch(move)
	{
		case 0: result = 8; break;
		case 1: result = 12;break;
		case 2: result = 10;break;
		case 3: result = 9; break;
		default: ;
	}
	return result;
}


/* Object Move */
void find_Method(int n)
{
	switch(n)
	{
		case 0: method0();break;
		case 1: method1();break;
		case 2: method2();break;
		case 3: method3();break;
		default: ;
	}
}

void method0()// M
{
	if(Objects[0] == 1)Objects[0] = 0;
	else Objects[0] = 1;
}

void method1()// M & C
{
	if(Objects[0] == 1)Objects[0] = 0;
	else Objects[0] = 1;
	
	if(Objects[1] == 1)Objects[1] = 0;
	else Objects[1] = 1;
}

void method2()// M & G
{
	if(Objects[0] == 1)Objects[0] = 0;
	else Objects[0] = 1;
	
	if(Objects[2] == 1)Objects[2] = 0;
	else Objects[2] = 1;
}

void method3()// M & W
{
	if(Objects[0] == 1)Objects[0] = 0;
	else Objects[0] = 1;
	
	if(Objects[3] == 1)Objects[3] = 0;
	else Objects[3] = 1;
}


/* Stack */
void push(int method)
{
	stack[++top] = method;
	find_Method(stack[top]); // rebound
}

void pop()
{
	find_Method(stack[top--]);
}


/* Print */
void print_Path()
{
	int i;
	if(flag == 0)flag = 1;
	else printf("\n");
	for(i=0; i<=top+1; i++)
	{
		switch( pathArray[i] ) {			// show all rather than required output
			case 0 : printf(".... <- MWGC\n");break;
			case 1 : printf("...C <- MWG.\n");break;
			case 2 : printf("..G. <- MW.C\n");break;
			case 3 : printf("..GC <- MW..\n");break;
			case 4 : printf(".W.. <- M.GC\n");break;
			case 5 : printf(".W.C <- M.G.\n");break;
			case 6 : printf(".WG. <- M..C\n");break;
			case 7 : printf(".WGC <- M...\n");break;
			case 8 : printf("M... -> .WGC\n");break;
			case 9 : printf("M..C -> .WG.\n");break;
			case 10: printf("M.G. -> .W.C\n");break;
			case 11: printf("M.GC -> .W..\n");break;
			case 12: printf("MW.. -> ..GC\n");break;
			case 13: printf("MW.C -> ..G.\n");break;
			case 14: printf("MWG. -> ...C\n");break;
			case 15: printf("MWGC -> ....\n");break;
			default: ;
		}
	}
}

void check_Result()
{
	if(flag == 0)printf("None");
}

代码人 ~ 代码魂 ~ 此生钟爱代码神 ~ Big_Kiss~

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
人狼羊菜过河一个经典的智力游戏,玩家需要帮助一群人、一只一只和一堆过河,但只能承载两个物品或人。同时,如果没有人看守,会被吃掉,而如果没有也会被吃掉。因此,玩家需要想出一个方案,让所有物品和人都安全地渡。 以下是人狼羊菜过河的 Python 实现示例: ```python # 定义初始状态 start = {'people': 1, 'wolf': 1, 'sheep': 1, 'vegetable': 1, 'boat': 0} # 定义目标状态 goal = {'people': 0, 'wolf': 0, 'sheep': 0, 'vegetable': 0, 'boat': 1} # 定义移动函数 def move(state, p, q): new_state = state.copy() new_state['people'] -= p new_state['wolf'] -= q new_state['sheep'] += q new_state['vegetable'] += p new_state['boat'] = 1 - state['boat'] return new_state # 定义判断函数 def is_valid(state): if state['wolf'] == state['sheep'] and state['people'] != state['wolf']: return False if state['sheep'] == state['vegetable'] and state['people'] != state['sheep']: return False return True # 定义搜索函数 def search(start, goal): visited = set() queue = [[start]] while queue: path = queue.pop(0) last_state = path[-1] if last_state == goal: return path for p in range(2): for q in range(2): if p + q == 0 or p + q == 2: continue new_state = move(last_state, p, q) if is_valid(new_state) and tuple(new_state.items()) not in visited: visited.add(tuple(new_state.items())) new_path = path + [new_state] queue.append(new_path) # 运行搜索函数并输出结果 result = search(start, goal) for state in result: print(state) ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值