2023年全國碩士研究生考試考研英語一試題真題(含答案詳解+作文范文)_第1頁
已閱讀1頁,還剩9頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、<p><b>  數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)</b></p><p><b>  修道士野人過河問題</b></p><p><b>  修道士與野人問題</b></p><p>  假設(shè)有n個修道士和n個野人準(zhǔn)備渡河,但只有一條能容納c人的小船,為了防止野人侵犯修道士,要求無論在何處,修道士的個數(shù)

2、不得少于野人的人數(shù)(除非修道士個數(shù)為0)。如果兩種人都會劃船,試設(shè)計(jì)一個算法,確定他們能否渡過河去,若能,則給出一個小船來回次數(shù)最少的最佳方案。</p><p> ?。?)用一個三元組(x1,x2,x3)表示渡河過程中各個狀態(tài)。其中,x1表示起始岸上修道士個數(shù),x2表示起始岸上野人個數(shù),x3表示小船位置(0——在目的岸,1——在起始岸)。例如(2,1,1)表示起始岸上有兩個修道士,一個野人,小船在起始岸一邊。&l

3、t;/p><p>  采用鄰接表做為存儲結(jié)構(gòu),將各種狀態(tài)之間的遷移圖保存下來。</p><p> ?。?)采用廣度搜索法,得到首先搜索到的邊數(shù)最少的一條通路。</p><p><b> ?。?)輸出數(shù)據(jù)</b></p><p>  若問題有解(能渡過河去),則輸出一個最佳方案。用三元組表示渡河過程中的狀態(tài),并用箭頭指出這些狀

4、態(tài)之間的遷移</p><p>  若問題無解,則給出“渡河失敗”的信息。</p><p> ?。?)求出所有的解。</p><p><b>  1.需求分析</b></p><p>  有n個修道士和n個野人準(zhǔn)備渡河,但只有一條能容納c人的小船,為了防止野人侵犯修道士,要求無論在何處,修道士的個數(shù)不得少于野人的人數(shù),否則

5、修道士就會有危險(xiǎn),設(shè)計(jì)一個算法,確定他們能否渡過河去,若能,則給出一個小船來回次數(shù)最少的最佳方案。用三元組(x1,x2,x3)來表示渡河過程中各個狀態(tài),其中,x1表示起始岸上修道士個數(shù),x2表示起始岸上野人個數(shù),x3表示小船位置(0——在目的岸,1——在起始岸)。若問題有解(能渡過河去),則輸出一個最佳方案。用三元組表示渡河過程中的狀態(tài),并用箭頭指出這些狀態(tài)之間的遷移:目的狀態(tài)←…中間狀態(tài)←…初始狀態(tài),若問題無解,則給出“渡河失敗”的信

6、息。</p><p><b>  2.設(shè)計(jì)</b></p><p><b>  2.1 設(shè)計(jì)思想</b></p><p><b> ?。?)數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)</b></p><p>  邏輯結(jié)構(gòu)設(shè)計(jì): 圖型結(jié)構(gòu)</p><p>  存儲結(jié)構(gòu)設(shè)計(jì): 鏈?zhǔn)酱鎯Y(jié)

7、構(gòu)</p><p>  采用這種數(shù)據(jù)結(jié)構(gòu)的好處:便于采用廣度搜索法,得到首先搜索到的邊數(shù)最少的一條通路,輸出一個最佳方案,采用圖的鄰接表存儲結(jié)構(gòu)搜索效率較高。</p><p><b>  (2)算法設(shè)計(jì)</b></p><p>  算法設(shè)計(jì)的總體設(shè)計(jì)思路為:在得到修道士人數(shù)和小船的容納人數(shù)后,用boatcase得到所有情況,然后再進(jìn)行安全性檢查

8、,以減去修道士少于野人的情況,接著用孩子兄弟結(jié)點(diǎn)表示法,將去對面的路作為孩子結(jié)點(diǎn),路與路是兄弟關(guān)系,到達(dá)另一邊時(shí),同樣以這種方法,直到找到(0,0,0)。主要分為4個模塊:boatcase生成所有情況,BFS得到邊數(shù)最少的最佳方案,safe安全性檢測,print輸出安全渡河的全過程。</p><p>  各個模塊要完成的主要功能分別為:</p><p>  生成模塊:生成所有的可能渡河情況

9、</p><p>  安全檢測模塊:對所有的可能渡河情況進(jìn)行安全檢測,,以減去修道士少于野人的情況</p><p>  廣度搜索模塊:采用廣度搜索法,得到首先搜索到的邊數(shù)最少的一條通路</p><p>  輸出模塊:輸出所有安全渡河的全過程</p><p> ?。?)函數(shù)接口規(guī)格說明</p><p>  void Li

10、nkinit(Link **head)</p><p>  void insertson(Link *head, DataType x)</p><p>  void insertbro(Link *head,DataType x)</p><p>  int boatcase(DataType x,int n) </p><p>  voi

11、d guangdu(Link *p,int n,int c)</p><p>  int safe(DataType x,int n)</p><p>  void print(Link *q,Link *p)</p><p><b>  3.調(diào)試分析</b></p><p>  (1)本題是采用鄰接表做為存儲結(jié)構(gòu),將各

12、種狀態(tài)之間的遷移圖保存下來,并用孩子兄弟表示法,以實(shí)現(xiàn)廣度搜索;剛編好程序時(shí)出現(xiàn)死循環(huán)的現(xiàn)象,例如:帶過去2個野人又帶回來2個野人,在和其他同學(xué)討論后,采用了2個標(biāo)志位來避免出現(xiàn)死循環(huán)的現(xiàn)象,在進(jìn)行運(yùn)行的時(shí)候,曾出現(xiàn)了打印輸出錯誤,經(jīng)過一步一步調(diào)試,發(fā)現(xiàn)在插入結(jié)點(diǎn)的時(shí)候出現(xiàn)了插入錯誤,即沒有考慮到pre的改變,通過改正,重新運(yùn)行檢測,運(yùn)行結(jié)果正確,在排版時(shí)通過一步步調(diào)試,參考了課本和老師的課件,并與和其他同學(xué)討論后,終于通過調(diào)試和改正,

13、,能夠使輸出結(jié)果很明顯的渡河方案。</p><p>  (2)可改進(jìn)內(nèi)容:顯示表示哪些是渡河次數(shù)最短的,最佳渡河方案一共有幾種,并輸出每種最佳渡河方案,另外,可嘗試用深度優(yōu)先搜索算法來找最佳方案。</p><p><b>  4.用戶手冊</b></p><p>  本程序在VC++6.0環(huán)境下運(yùn)行,根據(jù)提示輸入相應(yīng)的渡河人數(shù)和小船能容納的人數(shù)

14、即可。</p><p>  5.測試數(shù)據(jù)及測試結(jié)果</p><p><b>  測試用例1</b></p><p>  測試輸入: n=3,c=2</p><p>  測試目的: 檢驗(yàn)程序運(yùn)行時(shí)是否會陷入死循環(huán)</p><p><b>  正確輸出: 見截屏</b></

15、p><p><b>  輸入情況圖如上</b></p><p>  統(tǒng)計(jì)及循環(huán)效果圖如上</p><p><b>  6.源程序清單</b></p><p>  #include <stdio.h></p><p>  #include <malloc.h>

16、;</p><p>  #include <stdlib.h></p><p>  typedef struct </p><p><b>  {</b></p><p>  int xds; //修道士個數(shù)</p><p>  int yr; //野人個數(shù)</p>

17、<p>  int cw; //船的位置</p><p>  }DataType;</p><p>  DataType array[50000];</p><p>  typedef struct node//結(jié)構(gòu)體定義</p><p><b>  {</b></p><p> 

18、 DataType data;</p><p>  struct node *son;//兒子</p><p>  struct node *bro;//兄弟</p><p>  struct node *par;//雙親</p><p>  struct node *next;</p><p><b>  

19、}Link;</b></p><p>  void Linkinit(Link **head) //初始化操作</p><p><b>  {</b></p><p>  *head=(Link *)malloc(sizeof (Link)); //申請動態(tài)空間</p><p>  (*head)-&

20、gt;son=NULL;</p><p>  (*head)->bro=NULL;</p><p>  (*head)->par=NULL;</p><p>  (*head)->next=NULL;</p><p><b>  }</b></p><p>  void inse

21、rtson(Link *head, DataType x) //在鄰接表中插入兒子結(jié)點(diǎn)的操作</p><p><b>  {</b></p><p>  Link *q,*s;</p><p>  q=(Link *)malloc(sizeof (Link));</p><p>  q->data=x;<

22、/p><p>  head->son=q;//將x插入給頭結(jié)點(diǎn)的兒子指針</p><p><b>  s=head;</b></p><p>  while (s->next!=NULL)</p><p>  s=s->next;</p><p>  q->par=head;&

23、lt;/p><p>  q->son=NULL;</p><p>  q->bro=NULL;</p><p>  s->next=q;</p><p>  q->next=NULL;</p><p><b>  }</b></p><p>  void

24、 insertbro(Link *head,DataType x)//在鄰接表中插入兄弟結(jié)點(diǎn)的操作,</p><p>  //所有的兄弟結(jié)點(diǎn)都指向他們右邊的結(jié)點(diǎn)</p><p><b>  {</b></p><p>  Link *q,*s;</p><p>  q=(Link *)malloc(sizeof (Lin

25、k));</p><p>  s=head->son;</p><p>  q->data=x;</p><p>  while (s->bro!=NULL)</p><p><b>  s=s->bro;</b></p><p><b>  s->bro=

26、q;</b></p><p>  s->next=q;</p><p>  q->next=NULL;</p><p>  q->bro=NULL;</p><p>  q->par=head;</p><p>  q->son=NULL;</p><p&g

27、t;<b>  }</b></p><p>  int boatcase(DataType x,int n) //生成所有情況;</p><p><b>  {</b></p><p>  int i=0,a,b,t=0;</p><p>  if(x.cw) //在此岸,上船的人多優(yōu)先<

28、/p><p><b>  {</b></p><p>  a=0;b=n-a; //a為修道士b為野人</p><p>  while (a+b>=1)//當(dāng)船上有人時(shí)</p><p><b>  {</b></p><p><b>  t++;</b>

29、;</p><p>  while (b>=0)//當(dāng)野人個數(shù)不為負(fù)數(shù)</p><p>  { </p><p>  array[i].xds=a;</p><p>  array[i].yr=b;</p><p><b>  i++;</b></p

30、><p><b>  a++;</b></p><p><b>  b--;</b></p><p><b>  }</b></p><p>  a=0;//船上空位個數(shù)</p><p><b>  b=n-a-t;</b></p

31、><p><b>  }</b></p><p><b>  }</b></p><p>  else//在對岸,上船的人少優(yōu)先</p><p><b>  {</b></p><p>  a=1;b=0;t=0;</p><p> 

32、 while (a+b<=n)</p><p><b>  {</b></p><p>  t++;//船上的人數(shù)</p><p>  while (a>=0)</p><p>  { </p><p>  array[i].xds=a*(-1);<

33、/p><p>  array[i].yr=b*(-1);</p><p><b>  i++;</b></p><p><b>  a--;</b></p><p><b>  b++;</b></p><p><b>  } </b>

34、</p><p>  a=array[0].xds*(-1)+t;</p><p><b>  b=0;</b></p><p><b>  }</b></p><p><b>  }</b></p><p>  return i; //i為總數(shù)量&l

35、t;/p><p><b>  }</b></p><p>  int safe(DataType x,int n)//安全性檢測</p><p><b>  { </b></p><p>  if ((x.xds>=x.yr||x.xds==0)&&((n-x.xds)>=(

36、n-x.yr)||x.xds==n)&&x.xds>=0&&x.xds<=n&&x.yr>=0&&x.yr<=n)</p><p>  return 1;//船上修道士</p><p><b>  else</b></p><p><b>  re

37、turn 0;</b></p><p><b>  }</b></p><p>  void print(Link *q,Link *p) //打印安全渡河的過程,當(dāng)船到對岸時(shí),把對岸當(dāng)作其始岸,此岸當(dāng)作彼岸</p><p><b>  {</b></p><p>  DataT

38、ype a[100];</p><p><b>  int i=1;</b></p><p>  a[0].cw=0;</p><p>  a[0].xds=0;</p><p>  a[0].yr=0;</p><p>  while (q!=p)//避免出現(xiàn)相同情況而循環(huán)</p>

39、<p><b>  {</b></p><p>  a[i++]=q->data;//將一次過河的情況給b[i]</p><p><b>  q=q->par;</b></p><p><b>  }</b></p><p>  while ((--i)

40、>-1) //輸出過河圖 </p><p><b>  {</b></p><p>  printf("( %d %d %d )",a[i].xds,a[i].yr,a[i].cw);</p><p>  if (!(a[i].xds==0&&a[i].yr==0&&a[i].cw

41、==0)) </p><p><b>  {</b></p><p>  if(a[i].cw==1) </p><p>  printf("-->(%d %d)-->(%d %d 0)\n",a[i].xds-a[i-1].xds,a[i].yr-a[i-1].yr,a[i-1].xds,a

42、[i-1].yr);</p><p>  //a[i].xds-a[i-1].xds表示過河過程中船上的修道士數(shù),a[i].yr-a[i-1].yr表示過河過程中船上的野人數(shù)</p><p><b>  else</b></p><p>  printf(" <-- ( %d %d ) <-- ( %d %d 1 )\n&

43、quot;,(a[i].xds-a[i-1].xds)*(-1),(-1)*(a[i].yr-a[i-1].yr),a[i-1].xds,a[i-1].yr);</p><p><b>  }</b></p><p><b>  }</b></p><p>  printf("渡河成功!\n");<

44、;/p><p><b>  }</b></p><p>  void guangdu(Link *p,int n,int c)//廣度搜索 </p><p><b>  {</b></p><p>  Link *q,*t;</p><p>  DataType tem;<

45、/p><p>  int i,flag1,flag2,g=0,j,count=0;</p><p><b>  q=p->son;</b></p><p>  while (q!=NULL) </p><p><b>  {</b></p><p>  flag1=0;

46、 j=boatcase(q->data,c);//可能過河的情況</p><p>  for (i=0;i<j;i++)//搜索兄弟結(jié)點(diǎn)</p><p><b>  {</b></p><p>  tem.xds=q->data.xds-array[i].xds;</p><p>  tem.

47、yr=q->data.yr-array[i].yr;</p><p>  tem.cw=1-q->data.cw;</p><p><b>  t=q;</b></p><p>  if (safe(tem,n))//是否安全</p><p><b>  {</b></p>

48、<p>  flag2=1;//1表示沒有死循環(huán)</p><p>  while (t!=p)//保證不會出現(xiàn)循環(huán)</p><p><b>  {</b></p><p>  if(tem.xds== t->data.xds&&tem.yr==t->data.yr&&tem.cw==t-&

49、gt;data.cw)</p><p>  {//出現(xiàn)相當(dāng)情況時(shí)候</p><p><b>  flag2=0;</b></p><p>  break; </p><p><b>  }</b></p><p><b>  t=t-&

50、gt;par;</b></p><p><b>  }</b></p><p>  if(flag2==1)</p><p><b>  {</b></p><p>  if (flag1==0) {</p><p>  in

51、sertson(q, tem);</p><p><b>  flag1=1;</b></p><p><b>  }</b></p><p><b>  else </b></p><p>  insertbro(q,tem);

52、 </p><p>  if (tem.xds==0&&tem.yr==0&&tem.cw==0)</p><p><b>  {</b></p><p>  print(q,p);</p><p><b>  count+

53、+;</b></p><p><b>  }</b></p><p>  } </p><p><b>  } </b></p><p><b>  } </b></p><p>  q=q->

54、next;</p><p><b>  } </b></p><p>  if (count==0)</p><p>  printf("無法成功渡河!\n");</p><p><b>  else</b></p><p>  printf("

55、;有%d種渡河方式。\n",count);</p><p><b>  }</b></p><p>  int main()</p><p><b>  {</b></p><p>  int n,c,back;</p><p><b>  Link *p

56、;</b></p><p>  DataType tem;</p><p>  while (back)</p><p><b>  {</b></p><p>  printf("請輸入修道士與野人的人數(shù)n:\n");</p><p>  scanf("

57、%d",&n);</p><p><b>  if (n==0)</b></p><p><b>  break;</b></p><p>  printf("請輸入船可容納的人數(shù)c:\n");</p><p>  scanf("%d",&a

58、mp;c);</p><p>  tem.xds=n;</p><p><b>  tem.yr=n;</b></p><p><b>  tem.cw=1;</b></p><p>  Linkinit(&p); //初始化鄰接表;</p><p>  inser

59、tson(p, tem); //將初始狀態(tài)作為頭結(jié)點(diǎn)的孩子結(jié)點(diǎn);</p><p>  guangdu(p,n,c); //進(jìn)行廣度搜索;</p><p>  printf("是否繼續(xù)?(繼續(xù) 1 ,退出 0 )\n");</p><p>  scanf("%d",&back);</p><p>

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 眾賞文庫僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論