1. 程式人生 > >資料結構與演算法:關於野人過河問題的課程設計

資料結構與演算法:關於野人過河問題的課程設計

野人過河問題
【問題描述】
有x個野人和y個傳教士來到河邊渡河,河岸有一條船,每次至多可供2人乘渡,野人和傳教士都會划船。在河岸,如果野人人數多於傳教士人數,則野人會吃掉傳教士。請設計一個程式來描述安全過河過程。
【基本要求】
(1)在河兩岸和船上要求野人的人數不大於傳教士的人數。
(2)要求輸出所有可能的過程。(即不同方法的每個步驟如示例1)
(3)要求對各個模組的功能及引數作必要的說明。
【實現提示】
(1)先設定兩個狀態陣列確定左岸和右岸,再確定狀態變數:野人數,傳教士數和船。
(2)先從開始岸考慮傳教士數>=野人數,河對岸野人數<=傳教士數。並且始終保證開過去兩人,開回來一人實現有效轉換。
(3)可以考慮使用圖搜尋方法,通過檢測結點來實現路徑的輸出。
輸出示例:
第1次:左岸到右岸,傳教士過去1人,野人過去1人
第2次:右岸到左岸,傳教士過去1人,野人過去0人
第3次:左岸到右岸,傳教士過去0人,野人過去2人
第4次:右岸到左岸,傳教士過去0人,野人過去1人
第5次:左岸到右岸,傳教士過去2人,野人過去0人
第6次:右岸到左岸,傳教士過去1人,野人過去1人
第7次:左岸到右岸,傳教士過去2人,野人過去0人
第8次:右岸到左岸,傳教士過去0人,野人過去1人
第9次:左岸到右岸,傳教士過去0人,野人過去2人
第10次:右岸到左岸,傳教士過去0人,野人過去1人
第11次:左岸到右岸,傳教士過去0人,野人過去2人
解答方法:

#include "stdio.h"
#include "cstdlib"
#define MAX 100
struct gh
{
	int left_c;
	int left_yr;
	int boat_location;
};
struct gh gharr[MAX];
int index=0;
int numpass=0;
int start_c,start_yr;


int handle(gh t)
{
	if(t.left_c == 0 && t.left_yr == 0)
		{
			
			numpass++;
				printf("\n找到第%d條路徑:\n",numpass);
				for(int i = 1; i <= index ; i++)
				{
					printf("第%d次:",i);
					if(gharr[i].boat_location==1)
					printf("右岸到左岸,");
					else printf("左岸到右岸,");
					printf("傳教士過去%2d人,",abs(gharr[i].left_c-gharr[i-1].left_c));
					printf("野人過去%2d人",abs(gharr[i].left_yr-gharr[i-1].left_yr));
					printf("\n");
				}
	
			return 0;
		}

	for(int i = 0; i < index; i++)
	{
		if(t.left_c == gharr[i].left_c && t.left_yr == gharr[i].left_yr)
		{
			if(t.boat_location == gharr[i].boat_location)
			{
				return 0;
			}
			
		}
	}

	if(t.left_c < 0 || t.left_yr < 0 || t.left_c > start_c  || t.left_yr > start_yr  )
	{
		return 0;
	}

	if((t.left_c < t.left_yr && t.left_c != 0) || (start_c-t.left_c < start_yr-t.left_yr && start_c-t.left_c != 0) )
	{
		return 0;
	}


	struct gh tt;


	tt.left_c = t.left_c - 2 * t.boat_location;
	tt.left_yr = t.left_yr;
	tt.boat_location = ( -t.boat_location);
	index = index + 1;
	gharr[index] = tt;
	handle(gharr[index]);
	index = index - 1;
	

	tt.left_c = t.left_c;
	tt.left_yr = t.left_yr - 2 * t.boat_location;
	tt.boat_location = ( -t.boat_location);
	index = index + 1;
	gharr[index] = tt;
	handle(gharr[index]);
	index = index-1;	


	tt.left_c = t.left_c - 1 * t.boat_location;
	tt.left_yr = t.left_yr - 1 * t.boat_location;
	tt.boat_location = ( -t.boat_location);
	index = index + 1;
	gharr[index] = tt;
	handle(gharr[index]);
	index = index-1;


	tt.left_c = t.left_c - 1 * t.boat_location;
	tt.left_yr = t.left_yr;
	tt.boat_location = ( -t.boat_location);
	index = index + 1;
	gharr[index] = tt;
	handle(gharr[index]);
	index = index-1;


	tt.left_c = t.left_c;
	tt.left_yr = t.left_yr - 1 * t.boat_location;
	tt.boat_location = ( -t.boat_location);
	index = index + 1;
	gharr[index] = tt;
	handle(gharr[index]);
	index = index-1;
	return 0;
}


void main()
{
	printf("請輸入初始傳教士人數:");
	scanf("%d",&start_c);
	printf("請輸入初始野人人數:");
	scanf("%d",&start_yr);
	gharr[index].left_c = start_c;
	gharr[index].left_yr = start_yr;
	gharr[index].boat_location = 1;
	handle(gharr[index]);
	if(numpass==0)
			printf("不可能過河!\n");
	else printf("已為您找到%d條過河路徑!並且已全部載入完畢!\n",numpass);
}