【 日常 】 马跳日问题 18年3月17日18:09 [ 12 ]

/*前言: 好多天前准备记录下自己的坎坷修仙的点滴,以后希望能留下【珍贵的回忆】,萌新的日常代码,大佬互喷*/

萌新代码写的比较繁琐,各位路过,飘过,飞过大佬互喷

开始感觉这题目思路蛮清晰蛮简单的,敲着敲着,敲进去了,迷的一匹,花了很多时间 。感觉有点缺陷没有将路径显示出来

只是记录了最优步数。额恩,蛋疼....

/*
0 1  起始位置
6 5  终点位置
5  障碍物个数
1 1      |
1 2      |
2 3      |
0 5      |
3 3   障碍物坐标
*/

# include <iostream>
# include <queue>  //本代码为了简便使用了C++ StL中的队列容器
# define Horse_Band 200 //初设 马的活动边界为 8*8 的正方形
# define TAB "  "
using namespace std;
struct Node
{
	int X;
	int Y;
};
//为了方便设置成全局变量
int Horse_Move[Horse_Band][Horse_Band];//用二维数组来模拟活动,0 为无障碍物,1 为右障碍物
int Horse_Path[Horse_Band][Horse_Band];//用于标记已走步子
int Count_Pace = 0;//计步数
bool Check_IsOK(int(*pTemp)[Horse_Band], Node Current_pace, Node Bool_pace) {
//马有8个方向可走,当遇到0代表可走,1代表有障碍物不可走,并且和象棋规则一样有蹩马腿的限制
	if (!((0 <= Bool_pace.X&&Bool_pace.X < Horse_Band) && (0 <= Bool_pace.Y&&Bool_pace.Y < Horse_Band)))//不在地图中代表越界
		return false;
	//此时代表判断地在地图内,需要判断是否有障碍物
	//障碍物有两处:判断点和蹩马腿
	if (pTemp[Bool_pace.X][Bool_pace.Y] == 1)//终点障碍物
		return false;
	if (Current_pace.Y < Bool_pace.Y) {//说明蹩东马腿
		if (pTemp[Current_pace.X][Current_pace.Y + 1] == 1)//判断(X, Current.Y+1)处是否为1
			return false;
		return true;
	}
	else if (Current_pace.Y > Bool_pace.Y) {//此时蹩西马腿
		if (pTemp[Current_pace.X][Current_pace.Y - 1] == 1)//判断(X, Current.Y-1)处是否为1
			return false;
		return true;
	}
	else {
		//此时同一列说明南北方向
		if (Current_pace.X > Bool_pace.X) {//说明蹩北马腿
			if (pTemp[Current_pace.X - 1][Current_pace.Y] == 1)
				return false;
			return true;
		}
		else {//此时蹩南马腿
			if (pTemp[Current_pace.X + 1][Current_pace.Y] == 1)
				return false;
			return true;
		}
	}
}
//东南西北方向
Node PUSH_QUEUE(queue<Node>& Queue_Path, Node Current_Pace,Node End_Pace,bool IsDo) {
	Node New_Pace=Current_Pace;
	Node Return_Node;//用于保存返回的结点
	Horse_Path[Current_Pace.X][Current_Pace.Y] = 1;//标记不可走,代表已走过
	int Dir = -1,FLAG=0;
	while (true) {
		if ((Dir != -1) && (Check_IsOK(Horse_Move, Current_Pace, New_Pace))){
			Queue_Path.push(New_Pace);
			if (IsDo&&FLAG==0) {//做返回结点
				Return_Node = New_Pace;
				FLAG++;
			}
			Horse_Path[New_Pace.X][New_Pace.Y] = 1;
			if (New_Pace.X == End_Pace.X&&New_Pace.Y == End_Pace.Y)
				return End_Pace;
		}
		Dir++;
		New_Pace = Current_Pace;//初始成当前位置
		switch (Dir) {
		case 0://东上  Y+2  X-1
			New_Pace.X = New_Pace.X - 1; New_Pace.Y = New_Pace.Y + 2;
			break;
		case 1://东下  Y+2  X+1
			New_Pace.X = New_Pace.X + 1; New_Pace.Y = New_Pace.Y + 2;
			break;
		case 2://南右  X+2  Y+1
			New_Pace.X = New_Pace.X + 2; New_Pace.Y = New_Pace.Y + 1;
			break;
		case 3://南左  X+2  Y-1
			New_Pace.X = New_Pace.X + 2; New_Pace.Y = New_Pace.Y - 1;
			break; 
		case 4://西下  Y-2  X+1
			New_Pace.X = New_Pace.X + 1; New_Pace.Y = New_Pace.Y - 2;
			break;
		case 5://西上  Y-2  X-1
			New_Pace.X = New_Pace.X - 1; New_Pace.Y = New_Pace.Y - 2;
			break;
		case 6://北左  X-2  Y-1
			New_Pace.X = New_Pace.X - 2; New_Pace.Y = New_Pace.Y - 1;
			break;
		case 7://北右 X-2  Y+1
			New_Pace.X = New_Pace.X - 2; New_Pace.Y = New_Pace.Y + 1;
			break;
		default:
			if (IsDo)
				return Return_Node;
			New_Pace.X = -1; New_Pace.Y = -1;//标记不在地图内返回回去
			return New_Pace;
		}
	}
}
//东南西北方向开始搜索
int Search_Path(queue<Node>& Queue_Path, Node Current_pace, Node End_pace){
	//队列思路,首先给出起始点与终点(与题目起始和终点相反)
	//然后用队列头到尾依次搜寻,每一步一循环,要标记每一步队列的开始一项,最后一项结束代表一步结束 ,开始第一项代表下一步搜索开始Count ++:
	Queue_Path.push(Current_pace);//将起始点压入队列
	Node First_Node = Queue_Path.back();
	Node Temp_Node;//临时结点接受返回结点
	bool IsDO = false;
	while (!Queue_Path.empty()){//只要队列非空就循环
		Current_pace = Queue_Path.front();
		if ((Current_pace.X == First_Node.X) && (Current_pace.Y == First_Node.Y))//该Count++
		{
			Count_Pace++;
			IsDO = true;//标记为该循环最后一步
		}
	//将此结点的8个方向全是遍历判断合格压入队列
		Temp_Node = PUSH_QUEUE(Queue_Path, Current_pace,End_pace,IsDO);
		if (Temp_Node.X != -1) {//代表是正常的返回值
			First_Node = Temp_Node;
			IsDO = false;
			if (First_Node.X == End_pace.X&&First_Node.Y == End_pace.Y)
				return Count_Pace;//游戏结束找到了最短路径
		}
		Queue_Path.pop();//将最上边的出队列
	}
	return (Count_Pace=-1);//代表走不到
}
int main(void)
{
	queue<Node> Queue_Path;
	Node Star_pace, End_pace; 
	int ZhangaiWU,n,m;
	cout << "请输入地图起点,终点 XY坐标 ,空格隔开" << endl;
	cin >> Star_pace.X >> Star_pace.Y >> End_pace.X >> End_pace.Y;
	cout << "请输入障碍物的个数以及坐标,空格隔开" << endl;
	cin >> ZhangaiWU;
//---------------------------------------
	for (int i = 0; i < Horse_Band; ++i) {
		for (int j = 0; j < Horse_Band; ++j)
			Horse_Move[n][m] = Horse_Path[n][m] = 0;
	}
	//初始化为全0 无障碍 图
//------------------------------------------
	for (int i = 0; i < ZhangaiWU; ++i){
		cin >> n >> m;
		Horse_Move[n][m] = Horse_Path[n][m] = 1;
	}
	//录入 障碍物的 坐标
//-------------------------------------------
	for (int i = 0; i < Horse_Band; ++i) {
		for (int j = 0; j < Horse_Band; ++j)
			if ((i == Star_pace.X&&j == Star_pace.Y) || (End_pace.X == i&&End_pace.Y == j))
				cout << "#" << TAB;
			else
				cout << Horse_Move[i][j] << TAB;
		cout << endl;
	}
	//坐标图情形的输出
//----------------------------------------------
	cout << endl << endl;
//	Search_Path(Queue_Path, Star_pace, End_pace);
	cout << Count_Pace << endl;
	system("pause");
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值