# include <stdio.h>
#define MAX 100
using namespace std;
struct cyzhuangtai //野人与传教士的位置
{
int leftc;
int rightc;
int lefty;
int righty;
int boatlocation;
};
int rulec[5]={1,2,0,1,0};
int ruley[5]={1,0,2,0,1};
struct cyzhuangtai zhuanhuan[MAX];
int index=0;
int num=0;
int startc,starty;
int handle(cyzhuangtai temp);
int main()
{
//printf("请输入初始传教士人数:");
//scanf("%d",&startc);
//printf("请输入初始野人人数:");
//scanf("%d",&starty);
starty=3;
startc=3;
zhuanhuan[index].leftc = startc;
zhuanhuan[index].lefty = starty;
zhuanhuan[index].rightc = 0;
zhuanhuan[index].righty = 0;
zhuanhuan[index].boatlocation = 1;
handle(zhuanhuan[index]);
printf("已为您找到%d条过河路径!并且已全部加载完毕!\n",num);
}
int handle(cyzhuangtai temp)
{
if( temp.rightc == startc && temp.righty == starty) //右岸的野人与传教士等于开始是的人数即(3,3);
{
num++;
printf("\n找到第%d条路径!\n",num);
printf("左传\t左野\t右传\t右野\t船\n");
for(int i = 0; i <= index ; i++)
{
printf("%2d\t",zhuanhuan[i].leftc);
printf("%2d\t",zhuanhuan[i].lefty);
printf("%2d\t",zhuanhuan[i].rightc);
printf("%2d\t",zhuanhuan[i].righty);
printf("%2d\t",zhuanhuan[i].boatlocation);
printf("\n");
}
return 0;
}
//是否重复操作
for(int i = 0; i < index; i++)
{
if(temp.leftc == zhuanhuan[i].leftc && temp.lefty == zhuanhuan[i].lefty)
{
if(temp.boatlocation == zhuanhuan[i].boatlocation)
{
return 0;
}
}
}
//人数是否合理吗
if(temp.leftc < 0 || temp.lefty < 0 || temp.rightc < 0 || temp.righty < 0 )
{
return 0;
}
//传教士是否被吃
if((temp.leftc < temp.lefty && temp.leftc != 0) || (temp.rightc < temp.righty && temp.rightc != 0) )
{
return 0;
}
/* printf("符合条件的路径\n");
printf("%2d\t",temp.leftc);
printf("%2d\t",temp.lefty);
printf("%2d\t",temp.rightc);
printf("%2d\t",temp.righty);
printf("%2d\t",temp.boatlocation);
printf("\n");*/
if(temp.boatlocation>0)
{
struct cyzhuangtai t;
for(int k=0;k<5;k++)
{
t.leftc=temp.leftc-rulec[k];
t.lefty = temp.lefty-ruley[k];
t.rightc = temp.rightc + rulec[k];
t.righty = temp.righty+ ruley[k];
t.boatlocation = ( -temp.boatlocation);
index = index + 1;
/*printf(">0");
printf("%2d\t",t.leftc);
printf("%2d\t",t.lefty);
printf("%2d\t",t.rightc);
printf("%2d\t",t.righty);
printf("%2d\t",t.boatlocation);
printf("**********\n");*/
zhuanhuan[index] = t;
handle(zhuanhuan[index]);
index = index-1;
}
}
if(temp.boatlocation<0)
{
struct cyzhuangtai t;
for(int j=0;j<5;j++)
{
t.leftc=temp.leftc+rulec[j];
t.lefty = temp.lefty+ruley[j];
t.rightc = temp.rightc - rulec[j];
t.righty = temp.righty- ruley[j];
t.boatlocation = ( -temp.boatlocation);
index = index + 1;
/* printf("<0");
printf("%2d\t",t.leftc);
printf("%2d\t",t.lefty);
printf("%2d\t",t.rightc);
printf("%2d\t",t.righty);
printf("%2d\t",t.boatlocation);
printf("**********\n");*/
zhuanhuan[index] = t;
handle(zhuanhuan[index]);
index = index-1;
}
}
}
実験レポート
1.実験プロジェクトの名前。
宣教師と野蛮人が川を渡る
2.プログラミング言語
c言語
3.データの物理構造設計
は構造配列を使用し、定義された構造は配列に入れられてパスを出力するか、存在するかどうかを確認しますパスを繰り返します。
4.クラスまたは関数の定義
struct cyzhuangtai //野蛮人と宣教師の場所を保存する
{
int leftc;
int rightc
;
int lefty;
int righty; int boatlocation;
};
int rulec [5] = {1,2,0,1,0};演算子
int ruley [5] = {1,0,2,0,1};
struct cyzhuangtai zhuanhuan [MAX];
int index = 0がとるパスを保存します;配列の添字は
int num = 0を意味します;記録されたパスの数
int startc、starty;最初の宣教師と野蛮人の
ハンドル数(cyzhuangtai temp)を示します;川を渡る5つの状況を処理する関数を再帰的に呼び出します
5.アルゴリズムの説明
プログラムでデータが修正され、宣教師と野蛮人の位置が初期化され、handle()関数が呼び出されます。handle()は再帰関数です。主に、目的の状態が満たされているか、操作が繰り返されているか、人数が妥当かどうかを判断します。宣教師が食べられたかどうかに関係なく、目標状態の出力が満たされるまで実行を続けます。そのような状態が発生した場合は、zhuanhuan []で前のレベルに戻り、新しい操作演算子に従ってハンドル()関数を実行します。
ここでは、右のバンクと左のバンクに別々に実行し、左のバンクではboatlocation> 0、右のバンクではboatlocation <0で、コードを別々に実行します。
6.実験運用結果
テストでは、野蛮人と宣教師の数を直接3とし、船の容量を2としています。