資料結構與演算法:關於野人過河問題的課程設計
阿新 • • 發佈:2018-12-27
野人過河問題
【問題描述】
有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); }