C语言关于过河问题的求大神指点啊

Lansing 2012-12-19 04:21:37
题目:有三个猎人带三头熊过河:其中有一头黑熊和两头棕熊!他们过河但只有一条船!已知猎人会划船 黑熊受过训练也会划船!每次只能上两熊或两人或一人一熊!如果当猎人比熊数量少的时候人就会被熊吃掉!问要怎么才能安全地带三只熊过河
#include "stdio.h"
#include"stdlib.h"

#define MaxVerNum 200 //最大顶点数

typedef enum{FALSE,TRUE}Boolean;
Boolean visited[MaxVerNum]; //对已访问的顶点标记
int path[MaxVerNum]; //保存DFS搜索到的路径,即与某顶点到下一顶点的路径


typedef struct
{
int a;
int b;
int c;
int d;
int e;
int f;
}VextexType;

typedef bool EdgeType;

typedef struct
{
VextexType vexs[MaxVerNum]; //顶点表
EdgeType edges[MaxVerNum][MaxVerNum]; //邻接矩阵,即边表
int n; //顶点数和边数
}MGraph; //MGraph是以邻接矩阵存储的图类型


int locate(MGraph *G,int A,int B,int C,int D,int E,int F) //查找顶点(R1,R2,R3,H,Z1,Z2)在顶点向量中的位置
{
int i;
for(i=0;i<G->n;i++)
if(G->vexs[i].a==A&&G->vexs[i].b==B&&G->vexs[i].c==C&&G->vexs[i].d==D&&G->vexs[i].e==E&&G->vexs[i].f==F)
return i; //返回当前位置
return -1; //没有找到此顶点
}

int is_safe(int A,int B,int C,int D,int E,int F)
{
if((A==D==E)||(A==D==F)||(A==E==F)||(A==D==E==F)||(B==D==E)||(B==D==F)||(B==E==F)||(B==D==E==F)||(C==D==E)||(C==D==F)||(C==E==F)||(C==D==E==F)||(A==B==D==E==F)||(A==C==D==E==F)||(C==B==D==E==F)) return 0; //当熊的数目多于人的时候是不安全的
else return 1;
}

int is_connected(MGraph *G,int i,int j) //判断状态i和j之间是否可以交换
{
int k=0;
if(G->vexs[i].a!=G->vexs[j].a) k++;
if(G->vexs[i].b!=G->vexs[j].b) k++;
if(G->vexs[i].c!=G->vexs[j].c) k++;
if(G->vexs[i].d!=G->vexs[j].d) k++;
if(G->vexs[i].e!=G->vexs[j].e) k++;
if(G->vexs[i].f!=G->vexs[j].f) k++;
if((G->vexs[i].a!=G->vexs[j].a)||(G->vexs[i].b!=G->vexs[j].b)||(G->vexs[i].c!=G->vexs[j].c)||(G->vexs[i].d!=G->vexs[j].d)&&k<=2)
return 1; //以上三个条件不同时满足且农夫状态改变时,返回真,即农夫每次只能带一件东西过船
else return 0;
}

void CreateG(MGraph *G)
{
int i,j,A,B,C,D,E,F;
i=0; //生成所有安全的图的顶点
for(A=0;A<=1;A++)
for(B=0;B<=1;B++)
for(C=0;C<=1;C++)
for(D=0;D<=1;D++)
for(E=0;E<=1;E++)
for(F=0;F<=1;F++)
if(is_safe(A,B,C,D,E,F))
{
G->vexs[i].a=A;
G->vexs[i].b=B;
G->vexs[i].c=C;
G->vexs[i].d=D;
G->vexs[i].e=E;
G->vexs[i].f=F;
i++;
}

G->n=i;
for(i=0;i<G->n;i++)
for(j=0;j<G->n;j++)
if(is_connected(G,i,j)) //状态i与j之间可以转化,初始化为1,否则为0
G->edges[i][j]=G->edges[j][i]=1;
else
G->edges[i][j]=G->edges[j][i]=0;
return ;
}

void print_path(MGraph *G,int u,int v) //输出从u到v之间的简单路径,即顶点序列中不重复的路径
{
int k,p=1;
k=u;
while(k!=v)
{
printf("第%d步:",p);
printf("\n(%d,%d,%d,%d,%d,%d)\n",G->vexs[k].a,G->vexs[k].b,G->vexs[k].c,G->vexs[k].d,G->vexs[k].e,G->vexs[k].f);
k=path[k];
p++;
}
printf("第%d步:",p);
printf("\n(%d,%d,%d,%d,%d,%d)\n",G->vexs[k].a,G->vexs[k].b,G->vexs[k].c,G->vexs[k].d,G->vexs[k].e,G->vexs[k].f);
p++;
}

void DFS_path(MGraph *G,int u,int v) //深度优先搜素从u到v的简单路径
{
int j;
visited[u]=TRUE; //标记已访问过得点
for(j=0;j<G->n;j++)
if(G->edges[u][j]&&!visited[j]&&!visited[v])
{
path[u]=j;
DFS_path(G,j,v);
}
}

void main()
{
int i,j;
MGraph graph;
CreateG(&graph);
for(i=0;i<graph.n;i++) visited[i]=FALSE; //置初值
i=locate(&graph,0,0,0,0,0,0);
j=locate(&graph,1,1,1,1,1,1);
DFS_path(&graph,i,j);
if(visited[j]) print_path(&graph,i,j);
}
图片不会插入
运行结果(手写的):
第一步:
<-858993460,-858993460,,-858993460,-858993460,-858993460,-858993460>
Press any key to continue


运行结果不对啊,代码有些繁多,求哪位大神能指出哪里出错啦?
小弟感激不尽!
...全文
424 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
Lansing 2012-12-20
  • 打赏
  • 举报
回复
有大神吗??求解啊!!!!!!!!!!
Lansing 2012-12-19
  • 打赏
  • 举报
回复
引用 1 楼 kuzuozhou 的回复:
传教士与野人过河问题。该算法题 360 2013校园招聘考到了。参考: http://blog.csdn.net/huangxy10/article/details/8066408 http://bbs.csdn.net/topics/390242017 贴段代码: C/C++ code?12345678910111213141516171819202122232……
我知道有其他类型的源代码啊 可是看不懂 用在这个问题上不知道怎么转换啊 对于数据结构我刚学 菜鸟一个 能不能就这个问题详细些啊?????????
Lansing 2012-12-19
  • 打赏
  • 举报
回复
引用 2 楼 lin5161678 的回复:
if((A==D==E)||(A==D==F)||(A==E==F)||(A==D==E==F)||(B==D==E)||(B==D==F)||(B==E==F)||(B==D==E==F)||(C==D==E)||(C==D==F)||(C==E==F)||(C==D==E==F)||(A==B==D==E==F)||(A==C==D==E==F)||(C==B==D=……
请问一下该怎么用啊 数据结构都是自学的额
lin5161678 2012-12-19
  • 打赏
  • 举报
回复
if((A==D==E)||(A==D==F)||(A==E==F)||(A==D==E==F)||(B==D==E)||(B==D==F)||(B==E==F)||(B==D==E==F)||(C==D==E)||(C==D==F)||(C==E==F)||(C==D==E==F)||(A==B==D==E==F)||(A==C==D==E==F)||(C==B==D==E==F)) 你确定你是想这样用??
pengfoo 2012-12-19
  • 打赏
  • 举报
回复
传教士与野人过河问题。该算法题 360 2013校园招聘考到了。参考: http://blog.csdn.net/huangxy10/article/details/8066408 http://bbs.csdn.net/topics/390242017 贴段代码:
#include <iostream>
#include <vector>
#include <string>
#include <stdio.h>
using namespace std;

bool flag = true; //true:表示在右岸
vector<string> visit; //记录已经访问过的状态

bool dfs( int M, int C, int m, int c){
	if( M<0||C<0||m<0||c<0)   //非法
		return false;
	if( (M&&C>M) ||(m&&c>m))   //野人会吃牧师
		return false;
	
	if( flag&&M==0&&C==0 ||(!flag&&m==0&&c==0))  //全部运输过去
		return true;

	//检查该节点是否出现过
	char s[30];
	if( !flag )
		sprintf( s, "M=%d,C=%d,m=%d,c=%d,boat=left", M,C,m,c);
	else
		sprintf( s, "M=%d,C=%d,m=%d,c=%d,boat=right", m,c,M,C);
	string str(s);
	for( int i=0; i<visit.size(); i++)
		if( visit[i]==str)                     //该状态已经搜索过了
			return false;

	visit.push_back(str);
	flag = !flag;
	if( dfs( m+2, c, M-2,C) ){
		printf("2,0\n");
		printf("%s\n",s);
		return true;
	}
	else if( dfs( m, c+2, M, C-2) ){
		printf("0,2\n");
		printf("%s\n",s);
		return true;
	}
	else if( dfs( m+1, c+1, M-1, C-1) ){
		printf("1,1\n");
		printf("%s\n",s);
		return true;
	}
	else if( dfs( m+1, c, M-1, C)){
		printf("1,0\n");
		printf("%s\n",s);
		return true;
	}
	else if( dfs( m, c+1, M, C-1)){
		printf("0,1\n");
		printf("%s\n",s);
		return true;
	}
	flag = !flag;
	visit.pop_back();
	return false;
}

int main(){
	char s[30];
	int M=6,C=6,m=0,c=0;
	sprintf( s, "M=%d,C=%d,m=%d,c=%d,boat=left", M,C,m,c);
	printf("%s\n",s);
	if(!dfs(M,C,0,0))
		cout << "Can not find the solution."<<endl;
	return 0;
}

3,881

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 其它技术问题
社区管理员
  • 其它技术问题社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧