AI.C
上传用户:bjtelijie
上传日期:2010-01-01
资源大小:87k
文件大小:7k
源码类别:

数学计算

开发平台:

Visual C++

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #define maxloop 100    //最大层数,对于不同的扩展方法自动调整取值 #define pristnum 3 #define slavenum 3 struct SPQ { int sr,pr;             //船运行一个来回后河右岸的野人、传教士的人数  int sl,pl;             //船运行一个来回后河左岸的野人、传教士的人数  int ssr,spr;           //回来(由左向右时)船上的人数 int sst,spt;           //去时(由右向左时)船上的人数 int loop;               //本结点所在的层数                  struct SPQ *upnode ,*nextnode;//本结点的父结点和同层的下一个结点的地址 }spq;   int loopnum;//记录总的扩展次数 int openednum;//记录已扩展节点个数 int unopenednum;//记录待扩展节点个数 int resultnum; struct SPQ *opened; struct SPQ *oend; struct SPQ *unopened;           struct SPQ *uend; struct SPQ *result; void initiate();
  4. void releasemem(); void showresult(); void addtoopened(struct SPQ *ntx); int search();
  5. void goon(); int stretch(struct SPQ* ntx);
  6. void recorder(); void main() { int flag;       //标记扩展是否成功
  7. for( ; ; ) { initiate(); flag = search (); if(flag == 1) { recorder(); releasemem(); showresult();
  8. goon(); } else { printf("无法找到符合条件的解");
  9. releasemem(); goon();
  10. } } } void initiate() { int x;
  11. char choice;
  12. uend = unopened = (struct SPQ*)malloc(sizeof(spq)); if(uend==NULL)
  13. {
  14. printf("n内存不够!n");
  15. exit(0);
  16. } unopenednum=1; openednum=0; unopened -> upnode = unopened;       //保存父结点的地址以成链表 unopened -> nextnode = unopened; unopened -> sr = slavenum; unopened -> pr = pristnum; unopened -> sl = 0; unopened -> pl = 0; unopened -> sst = 0; unopened -> spt = 0; unopened -> ssr = 0; unopened -> spr = 0; unopened -> loop = 0; printf("题目:设有n个传教士和m个野人来到河边,打算乘一只船从右岸到左岸去。n");
  17. printf("该船的负载能力为两人。在任何时候,如果野人人数超过传教士人数,野人n");
  18. printf("就会把传教士吃掉。他们怎样才能用这条船安全的把所有人都渡过河去?n");
  19. printf("n默认的n、m值皆为3n");
  20.     for(;;)
  21. {
  22. printf("n是否修改?(Y/N)");
  23. scanf("%s",&choice);
  24. choice=toupper(choice);
  25. if(choice=='Y')
  26. {
  27. printf("n请输入传教士人数");
  28. for(;;)
  29. {
  30. scanf("%d",&x);
  31. if(x>0)
  32. {
  33. unopened -> pr = x;
  34. break;
  35. }
  36. else printf("n输入值应大于0!n请重新输入");
  37. }
  38. printf("n请输入野人人数");
  39. for(;;)
  40. {
  41. scanf("%d",&x);
  42. if(x>0)
  43. {
  44. unopened -> sr = x;
  45. break;
  46. }
  47. else printf("n输入值应大于0!n请重新输入");
  48. }
  49. break;
  50. }
  51. if(choice=='N')break;
  52. } } int search() { int flag; struct SPQ *ntx;               //提供将要扩展的结点的指针 for( ; ; ) { ntx = unopened;        //从待扩展链表中提取最前面的一个 if(ntx->loop == maxloop) return 0;  addtoopened(ntx);       //将ntx加入已扩展链表,并将这个节点从待扩展链表中去掉
  53. flag = stretch(ntx);    //对ntx进行扩展,返回-1,0,1 if(flag == 1) return 1;  } } int stretch(struct SPQ *ntx) { int fsr , fpr ; //在右岸上的人数 int fsl , fpl ; //在左岸上的人数 int sst , spt ; //出发时在船上的人数 int ssr , spr ; //返回时船上的人数 struct SPQ *newnode; for (sst = 0 ; sst <=  2 ; sst++) //讨论不同的可能性并判断是否符合条件 { fsr = ntx -> sr; fpr = ntx -> pr; fsl = ntx -> sl; fpl = ntx -> pl; if ((sst <=  fsr) && (( 2 - sst) <=  fpr))//满足人数限制 { spt = 2 - sst; fsr = fsr - sst; fpr = fpr - spt; if((fpr ==  0) && (fsr ==  0))//搜索成功 {  newnode = (struct SPQ*) malloc (sizeof(spq));
  54. if(newnode==NULL)
  55. {
  56. printf("n内存不够!n");
  57. exit(0);
  58. } newnode -> upnode = ntx;       //保存父结点的地址以成链表 newnode -> nextnode = NULL; newnode -> sr = 0; newnode -> pr = 0; newnode -> sl = opened -> sr; newnode -> pl = opened -> pr; newnode -> sst = sst; newnode -> spt = spt; newnode -> ssr = 0; newnode -> spr = 0; newnode -> loop = ntx -> loop + 1; oend -> nextnode = newnode; oend = newnode; openednum++; return 1; }    else if ((fpr - fsr) * fpr >= 0) //判断是否满足传教士人数必须大于或等于野人人数 { fsl = fsl + sst; fpl = fpl + spt; for (ssr = 0 ; ssr <= 1 ; ssr++)                  //返回 { int ffsl , ffpl; if ((ssr <= fsl) && ((1 - ssr) <= fpl)) { spr = 1 - ssr; ffsl = fsl - ssr; ffpl = fpl - spr; if ((ffpl - ffsl) * ffpl >= 0) { //若符合条件则分配内存并付值 int  ffsr , ffpr; ffsr = fsr + ssr; ffpr = fpr + spr;                          newnode = (struct SPQ*) malloc (sizeof(spq));
  59. if(newnode==NULL)
  60. {
  61. printf("n内存不够!n");
  62. exit(0);
  63. } newnode -> upnode = ntx;       //保存父结点的地址以成链表 newnode -> sr = ffsr; newnode -> pr = ffpr; newnode -> sl = ffsl; newnode -> pl = ffpl; newnode -> sst = sst; newnode -> spt = spt; newnode -> ssr = ssr; newnode -> spr = spr; newnode -> loop = ntx -> loop + 1; uend -> nextnode = newnode; uend = newnode; unopenednum++; } } } } } }  return 0; } void addtoopened(struct SPQ *ntx) { unopened = unopened -> nextnode;
  64. unopenednum--;
  65. if (openednum == 0 ) oend = opened = ntx; oend -> nextnode = ntx; oend = ntx; openednum++; } void recorder() { int i , loop;
  66. struct SPQ *newnode;
  67. struct SPQ *ntx;
  68. loop = oend -> loop;
  69. ntx = oend; resultnum = 0; for( i = 0 ; i <= loop ; i++ ) { newnode = (struct SPQ*) malloc (sizeof(spq));
  70. if(newnode==NULL)
  71. {
  72. printf("n内存不够!n");
  73. exit(0);
  74. } newnode -> sr = ntx -> sr; newnode -> pr = ntx -> pr; newnode -> sl = ntx -> sl; newnode -> pl = ntx -> pl; newnode -> sst = ntx -> sst; newnode -> spt = ntx -> spt; newnode -> ssr = ntx -> ssr; newnode -> spr = ntx -> spr;
  75. newnode -> nextnode = NULL; ntx = ntx -> upnode; if(i == 0) result = newnode; newnode -> nextnode = result; result = newnode; resultnum++; } } void releasemem() { int i; struct SPQ* nodefree; for ( i = 1 ; i < openednum ; i++ ) { nodefree = opened; opened = opened -> nextnode; free(nodefree); } for ( i = 0 ; i < unopenednum ; i++ ) { nodefree = unopened; unopened = unopened -> nextnode; free(nodefree); } } void showresult() { int i;
  76.     int fsr , fpr ; //在右岸上的人数
  77. int fsl , fpl ; //在左岸上的人数
  78. struct SPQ* nodefree;
  79. printf("%d个传教士",result -> pr);
  80. printf("%d个野人",result -> sr);     printf("%d个传教士",result -> pl);
  81.     printf("%d个野人",result -> sl); for ( i = 1 ; i < resultnum ; i++ ) { nodefree = result; result = result -> nextnode; free(nodefree); printf("nnt左岸人数 船上人数及方向 右岸人数n");
  82. printf("第%d轮n",i);
  83. fpl = result -> pl - result -> spt + result -> spr;
  84. fpr = result -> pr - result -> spr;
  85. fsl = result -> sl - result -> sst + result -> ssr;
  86.         fsr = result -> sr - result -> ssr;
  87. printf("传教士%8d%8dt<-t%8dn",fpl,result -> spt,fpr);
  88. printf("野  人%8d%8dt<-t%8dn",fsl,result -> sst,fsr);
  89. printf("传教士%8d%8dt->t%8dn",result -> pl,result -> spr,result -> pr - result -> spr);
  90. printf("野  人%8d%8dt->t%8dn",result -> sl,result -> ssr,result -> sr - result -> ssr);
  91. } printf("n全体传教士和野人全部到达对岸"); free(result);
  92. } void goon()
  93. {
  94. char choice;
  95. for(;;)
  96. {
  97. printf("是否继续?(Y/N)n");
  98.     scanf ("%s" , &choice);
  99. choice=toupper(choice);
  100. if(choice=='Y')break;
  101. if(choice=='N')exit(0);
  102. }
  103. }