user-0 提问: 商人过河策略问题，我自己写的出了什么问题

回复:
user: user-1
content: 楼主和我采用的是穷举法，找出所有可能的组合，如果其中含有成功的组合，找到这个组合的生成路径就是最终的解法

user: user-0
content: 好的，大概思路就是这样，第一次发帖不懂格式，但是还是有大神回复提醒我真的好开森 感谢大神抽空看看你有什么毛病  我的水平真的很低，以为期末考试以后一辈子都和西语言没有关系了，可曾想作死的选了数学建模，现在正在和数模作业作艰苦卓绝的斗争，这回作业关系到数模公选课会不会挂科，(感觉要挂了，好想死)虽然坛子里大神都有了自己的思路了，但是还是（不自量力不得好死地）想要自己写写。

user: user-0
content: #include<stdio.h> typedef struct state /*定义两岸的状态，x是商人，y是仆人*/ { 	int x,y; }state;  state s1,s2,p[40],q[40];/*S1表示此岸状态，S2表示彼岸状态，p,q放过程的此岸状态s1*/ int k1=0,k2=0,total=0;/*k1,k2是p，q的下标计数，total是方案的计数*/   int judgestate(state e)/*判断状态是不是会杀人越货，不是的话返回1*/ { 	if(e.x==0) 		return 1; 	if(e.x>0&&e.x>=e.y) 			return 1;   	return 0; } int check1(state e)/*判断状态是不是和p过程某一步重复，不重复就返回1 */ { 	int i; 	for(i=0;i<=k1;i++) 	{ 		if(e.x==p[i].x&&e.y==p[i].y) 			return 0; 		else  			return 1; 	} } int check2(state e)/*判断状态是不是和q过程某一步重复，重复返回0*/ { { 	int i; 	for(i=0;i<=k2;i++) 	{ 		if(e.x==q[i].x&&e.y==q[i].y) 			return 0; 		else  			return 1; 	} } void prt()/*输出*/ { 	int i; 	total++; 	printf("the %dth method is:\n",total); 	for(i=0;i<k1;i++) 	{ 		printf("(%d,%d)\n",p[i].x,p[i].y); 		printf("|\n"); 		printf("(%d,%d)\n",q[i].x,q[i].y); 	} 	printf("\n"); }  void boat(state s1,state s2) { 	int i,j,m,n;/*(i,j)表示乘船过去的（商人，仆人），(m,n)表示乘船回来的（商人，仆人）*/ 	for(i=0;i<=s1.x;i++)  		for(j=0;j<=s1.y;j++)/*乘船过去的人数应当少于当前此岸人数*/ 	 			if(i+j>0&&i+j<=2)/*小船只能坐两人*/ 			{ 				s1.x-=i; 				s1.y-=j; 				s2.x+=i; 				s2.y+=j; 				 				if(!judgestate(s1)||!judgestate(s2)||!check2(s1))/*判断这次改变是否会导致杀人越货 																 以及和之前的过程有重复，如果不满足 																条件就取消这次乘船，进入下一次循环*/ 				{ 					s1.x+=i; 					s1.y+=j; 					s2.x-=i; 					s2.y-=j; 					 					continue; 				} 				q[k2++]=s1;/*符合条件，就存储过程到数组*/ 	 				if(s2.x==3&&s2.y==3)/*判断是否全部安全运过去了，完成了就输出*/ 					prt();  				else/*没有完成还要往回运*/ 				{  					for(m=0;m<=s2.x;m++) 					  						for(n=0;n<=s2.y;n++)/*往回运的过程和运出去的差不多*/ 					  							if(i+j>0&&i+j<=2) 							{ 								s1.x+=m; 								s1.y+=n; 								s2.x-=m; 								s2.y-=n; 							 								if(!judgestate(s1)||!judgestate(s2)||!check1(s1)) 								{ 									s1.x-=m; 									s1.y-=n; 									s2.x+=m; 									s2.y+=n; 									continue; 								} 								p[++k1]=s2; 								boat(s1,s2);/*递归*/ 								 								s1.x-=m; 								s1.y-=n; 								s2.x+=m; 								s2.y+=n; 								--k1;/*递归回来了之后，恢复，继续循环下去*/ 							} 				} 		 				s1.x+=i; 				s1.y+=j; 				s2.x-=i; 				s2.y-=j; 				--k2; 			} } void main() { 		s1.x=3; 		s1.y=3; 		s2.x=0; 		s2.y=0; 		p[0]=s1;/*输入初始量*/ 		boat(s1,s2); } /*这思路很小白简单吧，可是没有结果，TAT,大神求求帮忙>3<*/

user: user-2
content: 要不然看起来真不方便

user: user-2
content: 这个真的是你写的吗？那你用代码格式重发一下代码，像这样—— #include<stdio.h> #include<stdlib.h> #include<conio.h> typedef struct state { 	int x,y; }state;  state s1,s2,p[40],q[40]; int k1=0,k2=0,total=0;   int judgestate(state e) { 	if(e.x==0) 	return 1; 	if(e.x>0&&e.x>=e.y) 	return 1; 	  	return 0; }另外给你的上面的变量标识一下，那些变量都代表什么

user: user-3
content: 是这样的思路吗？ 设商人为A B C 所带仆人分别为a b c渡河过程： 1 商人A带着随从a渡河 2 A将船划回来 3 b c两名随从接着划船渡河 4 c将船划回来 5 A B两名商人划船渡河 6 B b主仆二人划船回来 7 B C两名商人划船渡河 8 仆人a划船回来 9 仆人a b划船渡河 10 商人C划船回来 11 商人C带随从c划船渡河

user: user-1
content: 补充下： 1.状态是否复复应包括岸两边的状态与船的状态，不可只判断一边 2.生成的树的所有结点都记录下来供重复性判断，这样条理更清析

user: user-1
content: 问题一：你写的两个check函数中的for循环原本是想检查是否有重复步骤的，结果在else那也返回，导致只会判断一次  int check1(state e)/*判断状态是不是和p过程某一步重复，不重复就返回1 */ {     int i;     for(i=0;i<=k1;i++)     {         if(e.x==p[i].x&&e.y==p[i].y)             return 0;         else              return 1;     } }  问题二：楼主对p和q的状态判断有问题，导致死循环 当出现左岸商人为3，奴隶为0，右岸商人为0，奴隶为3，此时船在右岸，这种情况下楼主的思路 会出现死循环，情况如下： 商3奴0    ---商0奴3船 商3奴1船---商0奴2 商3奴0    ---商0奴3船 。。。。 改进思路是构建一棵树，树顶是初始状态商3奴3船---商0奴0 接下来根据不同走法生成不同的结点，当生成商0奴0---商3奴3船这样的结点时，表示成功，此时沿着该点到根 的路径就是解决方案，共2个方案

user: user-1
content: 按你的思路修改的，楼主的问题下一楼指出：   #include<stdio.h> #include<stdlib.h> #include<conio.h>  #define M_STATE_OK  0 #define M_STATE_ERR 1  #define M_MAX_CHILD_NUM 100 #define M_MAX_TREE_NODES  1000 #define M_MAX_SOLUTION_NODES 1000  typedef enum { 	T_DEFAULT = 0, 	T_S1TOS2, 	T_S2TOS1, }TRANS_T;  typedef struct { 	int master,slave,tmaster,tslave; 	TRANS_T tran;  }STATE_S;  typedef struct BOAT_TREE_S { 	STATE_S node; 	int     chileNum; 	struct BOAT_TREE_S* child[M_MAX_CHILD_NUM]; 	struct BOAT_TREE_S* parent; }BOAT_TREE_T;  BOAT_TREE_T treeNodes[M_MAX_TREE_NODES] = {0};  STATE_S solution[M_MAX_SOLUTION_NODES]={0};  int solutionNum=0,solutionIndex=0,treeNodesIndex = 0;  int check_err(STATE_S* s) { 	int i=0; 	 	if (NULL == s) 	{ 		printf("impossible err\n"); 		return M_STATE_ERR; 	} 	 	if ((s->master>0&&s->master<s->slave)||(s->tmaster>0&&s->tmaster<s->tslave)) 		return M_STATE_ERR; 	 	for (i=0;i<treeNodesIndex;i++) 	{ 		if (memcmp(&treeNodes[i].node,s,sizeof(STATE_S))==0) 		{ 			return M_STATE_ERR;		 		} 	} 	return M_STATE_OK; }  void tran_boat(BOAT_TREE_T* tree) { 	int i =0; 	int j =0; 	STATE_S tmp = {0}; 	BOAT_TREE_T* searchp = tree; 	 	if (NULL == tree) 	{ 		printf("error null point!\n"); 		return; 	} 	 	if (T_S1TOS2==tree->node.tran) 	{ 		for(i=0;i<=tree->node.master;i++) 			for(j=0;j<=tree->node.slave;j++) 			{ 				if (i+j>0&&i+j<=2) 				{ 					if (treeNodesIndex>M_MAX_TREE_NODES) 					{ 						printf("err:M_MAX_TREE_NODES\n"); 						exit(1); 					} 					 					memcpy(&treeNodes[treeNodesIndex].node,&tree->node,sizeof(STATE_S)); 				 					treeNodes[treeNodesIndex].node.master-=i; 					treeNodes[treeNodesIndex].node.slave-=j; 					treeNodes[treeNodesIndex].node.tmaster+=i; 					treeNodes[treeNodesIndex].node.tslave+=j; 					treeNodes[treeNodesIndex].node.tran = T_S2TOS1; 					 					if (treeNodes[treeNodesIndex].node.master==0&&treeNodes[treeNodesIndex].node.slave==0) 					{ 						solutionNum++; 						memcpy(&solution[solutionIndex],&treeNodes[treeNodesIndex].node,sizeof(STATE_S)); 						solutionIndex++; 						 						while (searchp!=NULL) 						{ 							memcpy(&solution[solutionIndex],&searchp->node,sizeof(STATE_S)); 							solutionIndex++; 							 							if (solutionIndex>M_MAX_SOLUTION_NODES)	 							{ 								printf("err:max solution\n"); 								exit(1); 							} 							searchp = searchp->parent; 						} 					} 					else if (check_err(&treeNodes[treeNodesIndex].node)!=M_STATE_ERR) 					{ 						if (tree->chileNum>=M_MAX_CHILD_NUM) 						{ 							printf("err:max child num!\n"); 							exit(1); 						} 						//memcpy(&treeNodes[treeNodesIndex].node,&tmp,sizeof(STATE_S)); 						treeNodes[treeNodesIndex].parent = tree; 						treeNodes[treeNodesIndex].chileNum = 0; 						tree->child[tree->chileNum] = &treeNodes[treeNodesIndex]; 						tree->chileNum++; 						treeNodesIndex++; 						tran_boat(&treeNodes[treeNodesIndex-1]); 					} 				} 			} 	} 	else if(T_S2TOS1==tree->node.tran) 	{ 		for(i=0;i<=tree->node.tmaster;i++) 			for(j=0;j<=tree->node.tslave;j++) 			{ 				if (i+j>0&&i+j<=2) 				{ 					if (treeNodesIndex>M_MAX_TREE_NODES) 					{ 						printf("err:M_MAX_TREE_NODES\n"); 						exit(1); 					} 					 					memcpy(&treeNodes[treeNodesIndex].node,&tree->node,sizeof(STATE_S)); 				 					treeNodes[treeNodesIndex].node.tmaster-=i; 					treeNodes[treeNodesIndex].node.tslave-=j; 					treeNodes[treeNodesIndex].node.master+=i; 					treeNodes[treeNodesIndex].node.slave+=j; 					treeNodes[treeNodesIndex].node.tran = T_S1TOS2; 					 					if (check_err(&treeNodes[treeNodesIndex].node)!=M_STATE_ERR) 					{ 						if (tree->chileNum>=M_MAX_CHILD_NUM) 						{ 							printf("err:max child num!\n"); 							exit(1); 						} 						//memcpy(&treeNodes[treeNodesIndex].node,&tmp,sizeof(STATE_S)); 						treeNodes[treeNodesIndex].parent = tree; 						treeNodes[treeNodesIndex].chileNum = 0; 						tree->child[tree->chileNum] = &treeNodes[treeNodesIndex]; 						tree->chileNum++; 						treeNodesIndex++; 						tran_boat(&treeNodes[treeNodesIndex-1]); 					} 				} 			} 	} 	else 	{ 		printf("error!\n"); 		exit(1); 	} }  void printsolution(void) { 	int master,slave,tmaster,tslave; 	TRANS_T tran;  	 	int i = 0; 	printf("total soution num:%d\n",solutionNum); 	 	for (i=solutionIndex-1;i>=0;i--) 	{ 		if (T_S1TOS2==solution[i].tran) 		{ 			printf("s1->s2:s1(%d,%d),s2(%d,%d)\n",solution[i].master,solution[i].slave,solution[i].tmaster,solution[i].tslave); 		} 		else if (T_S2TOS1==solution[i].tran) 		{ 			printf("s2->s1:s1(%d,%d),s2(%d,%d)\n",solution[i].master,solution[i].slave,solution[i].tmaster,solution[i].tslave); 		} 	} }  void main() { 	treeNodes[0].node.master = 3; 	treeNodes[0].node.slave = 3; 	treeNodes[0].node.tmaster = 0; 	treeNodes[0].node.tslave = 0; 	treeNodes[0].node.tran = T_S1TOS2; 	treeNodes[0].chileNum = 0; 	treeNodes[0].parent = NULL; 	 	treeNodesIndex++; 	 	tran_boat(&treeNodes[0]); 	printsolution(); }