杭电OJ 1026:Ignatius and the Princess I

43 篇文章 0 订阅
10 篇文章 0 订阅

比较麻烦的一道题目,自己刚开始思路不清楚,错了很多次,后来看了别人的解答,才找出错误的地方。

#include <iostream>
#include <queue>
#include <stack>
#include <fstream>

using namespace std;
int dir[][2] = {{-1,0},{1,0},{0,-1},{0,1}};
typedef struct node 
{
	int i, j;
	int time;
	friend bool operator<(node n1, node n2)//按照时间大小从小到大排列
	{
		return n1.time > n2.time;
	}
}Node;
typedef struct 
{
	int i;
	int j;
}Point;
char map[100][100];//记录整个地图
bool used[100][100];//标记是否已经搜索过
Point result[100][100];//记录达到某一点的前一个位置,通过回溯找到路径
int n, m;//表示地图的大小

int bfs()//广度搜索,返回到达终点的最小时间数值
{
	priority_queue<Node> Q;//优先级队列
	Node start;
	start.i = 0;
	start.j = 0;
	start.time = 0;
	Point tempP;
	tempP.i = -1;
	tempP.j = -1;
	result[0][0] = tempP;
	used[0][0] = true;
	Q.push(start);
	while(!Q.empty())
	{
		Node tempN = Q.top();
		Q.pop();
		for (int k = 0; k < 4;  ++ k)
		{
			int ni = tempN.i + dir[k][0];
			int nj = tempN.j + dir[k][1];
			if (ni >= 0 && ni < n && nj >= 0 && nj < m && !used[ni][nj] && map[ni][nj] != 'X')
			{
				Node temp;
				temp.i = ni;
				temp.j = nj;
				if (map[ni][nj] == '.')
					temp.time = tempN.time + 1;
				else
					temp.time = tempN.time + map[ni][nj] - '0' + 1;
				used[ni][nj] = true;
				Point tp;
				tp.i = tempN.i;
				tp.j = tempN.j;
				result[ni][nj] = tp;

				if (ni == n - 1 && nj == m - 1)
					return temp.time;
				Q.push(temp);
			}
		}
	}
	return -1;
}

int main ()
{
	while (cin >> n >> m)
	{
		for (int i = 0; i < n ; ++ i)
			for (int j = 0; j < m ; ++ j)
			{
				cin>>map[i][j];
				used[i][j] = false;
			}
			int t = bfs();
			if (t == -1)
			{
				cout<<"God please help our poor hero."<<endl;
				cout <<"FINISH"<<endl;
			}
			if (t != -1)
			{
				cout <<"It takes "<<t<<" seconds to reach the target position, let me show you the way."<<endl;
				stack<Point> path;
				Point pp ;
				pp.i = n - 1;
				pp.j = m - 1;
				path.push(pp);
				while (result[pp.i][pp.j].i != -1 && result[pp.i][pp.j].j != -1)
				{
					path.push(result[pp.i][pp.j]);
					pp = result[pp.i][pp.j];
				}
				int time = 1;
				pp = path.top();
				path.pop();
				while(!path.empty())
				{
					cout << time<<"s:("<<pp.i<<","<<pp.j<<")->("<<path.top().i<<","<<path.top().j<<")"<<endl;
					time ++;
					if (map[path.top().i][path.top().j] != '.')
					{
						int tt = map[path.top().i][path.top().j] - '0';
						for (int mm = 0; mm < tt; ++ mm)
						{
							cout <<time<<"s:FIGHT AT ("<<path.top().i<<","<<path.top().j<<")"<<endl;
							time ++;
						}
					}

					pp = path.top();
					path.pop();
				}
				cout <<"FINISH"<<endl;
			}	
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值