ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

C语言实现野人与传教士过河问题-改进版

2021-06-07 19:02:13  阅读:279  来源: 互联网

标签:arr right int C语言 野人 printf 改进版 boat left


人工智能大作业需要,A*算法的应用,我估摸着这个是纯属算是DFS,或者理解为递归。这个代码根据一位博主的C语言改进的。这位博主写的很详细,如果你还是看不懂他的讲解的话,建议你可以根据代码及运行结果手动模拟一遍就可以有一个清楚的认识了,我的改进就是让原来的代码更有一定的适用性,就是使船载量不是仅仅局限于2,而是能够适应更多的输入,同时使代码较为紧凑。把参考的原文放在下面。

#include <stdio.h>
#define MAX 100
//状态
struct Rec
{
	int left_c;		//左岸传教士
	int right_c;	//右岸传教士
	int left_y;		//左岸野人
	int right_y;	//右岸野人
	int boat_location;	//靠岸情况
};
struct rec_Cal
{
	int first, second;
};
struct Rec arr[MAX];
int index=0;		//下标
int numpass=0;		//成功的路径数量
int start_c,start_y, boat_member_max;//初始化
int cnt;

rec_Cal cal[MAX];

//计算当最大最船量为boat_member_max的所有乘船情况
void Cal()
{
	int st = 0;
	for(int i = 0; i <= boat_member_max; ++i)
	{
		if(i != 0)
			st = 0;
		else 
			st = 1;
		for(int j = st; j <= boat_member_max-i; ++j)
		{
			cnt++;
			cal[cnt].first = i, cal[cnt].second = j;
		}
	}
	printf("当船只最多承载%d个人的时候,合法的渡河方案\n", boat_member_max);
	printf("	----传教士人数----野人人数----\n");
	for(int i = 1; i <= cnt; ++i)
		printf("[%d] ----%5d	----%5d		----\n", i, 
			cal[i].first, cal[i].second);
//	printf("cnt = %d\n", cnt);
}

bool check(Rec t)
{
	//是否重复操作
	for(int i = 0; i < index; i++)
	{
		if((t.left_c == arr[i].left_c && t.left_y == arr[i].left_y) 
			&& (t.boat_location == arr[i].boat_location))
		{
			return false;
		}
	}
	//人数小于0 出错
	if(t.left_c < 0 || t.left_y < 0 || t.right_c < 0 || t.right_y < 0  )
	{
		return false;
	}
	
	/*
	传教士是否被吃
	1、左岸:在传教士人数 不等于0 的情况下,传教士人数 < 野人人数
	2、右岸:在传教士人数 不等于0 的情况下,传教士人数 < 野人人数
	*/
	if((t.left_c != 0 && t.left_c < t.left_y) || 
		(t.right_c < t.right_y && t.right_c != 0) )
	{
		return false;
	}
	return true;
}
int handle(Rec t)
{
	//是否达到目标状态
	if(	t.right_c == start_c && t.right_y == start_y)
	{
		numpass++;
		printf("\n找到第%d条路径!\n",numpass);
		printf("左岸传教士数\t左岸野人数\t右岸传教士数\t右岸野人数\t船值靠岸\n");
		for(int i = 0; i <= index; i++)
		{
			printf("%4d\t\t",arr[i].left_c);
			printf("%4d\t\t",arr[i].left_y);
			printf("%4d\t\t",arr[i].right_c);
			printf("%4d\t\t",arr[i].right_y);
			if(arr[i].boat_location == 1)
				printf("left");
			else 
				printf("right");
//			printf("%2d\t",arr[i].boat_location);
			printf("\n");
		}
		//找到多条路径的关键一
		return 0;
	}
	if(!check(t))  //查看是否满足条件
		return 0;
	for(int i = 1; i <= cnt; ++i)
	{
		//定义一个临时节点
		struct Rec ttt;
		ttt.left_c = t.left_c - cal[i].first * t.boat_location;
		ttt.left_y = t.left_y - cal[i].second * t.boat_location;
		ttt.right_c = t.right_c + cal[i].first * t.boat_location;
		ttt.right_y = t.right_y + cal[i].second * t.boat_location;
		ttt.boat_location = ( -1 * t.boat_location);
		arr[++index] = ttt;
		handle(arr[index]);			//递归调入点
		--index;
	}
	//找到多条路径的关键二
	return 0;
}


int main()
{
	printf("请输入初始传教士人数:");
	scanf("%d",&start_c);
	printf("请输入初始传教士人数:");
	scanf("%d",&start_y);
	printf("请输入最大船载量:");
	scanf("%d", &boat_member_max);
	arr[index].left_c = start_c;		//初始状态全部在左岸、目的状态全部在右岸
	arr[index].left_y = start_y;
	arr[index].right_c = 0;
	arr[index].right_y = 0;
	arr[index].boat_location = 1;		//初始状态船在左岸
	Cal();
	handle(arr[index]);
	printf("已为您找到%d条过河路径!并且已全部加载完毕!\n",numpass);
	return 0;
}

运行结果
在这里插入图片描述在这里插入图片描述

参考链接:C语言实现野人与传教士过河问题

标签:arr,right,int,C语言,野人,printf,改进版,boat,left
来源: https://blog.csdn.net/qq_43656353/article/details/117671644

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有