三中的一次普通测试(三)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/dev_cao/article/details/102710999

题目

南昌三中是一所百年名校,历史悠久,秉承勤朴忠勇校训,南昌三中校园风景优美,建筑物别致,有风雨球馆,体育馆,艺体楼,游泳馆等多个漂亮建筑物,对于这些建筑物,信奥社指导老师找到他学建筑的同学,让他帮忙绘制了一个地图。老师看到地图以后,突发奇想,觉得他要在某一个位置设置墙,然后就构造成了一个建筑物和墙的迷宫
现在,迷宫里只剩下哈利和塞德里克了,哈利只有在塞德里克前面拿到奖杯,才能赢得比赛。哈利只要能看到奖杯,就可以用飞来咒拿到它,所以,现在的问题是哈利如何能尽早地看到奖杯。
题目描述
哈利的视力非常好,他能从迷宫的一端沿直线看到迷宫的另一端(但他只能看八个方向——东北,东,东南,南,西南……),而且跑得非常快,跑一步(向上、下、左、右移动一格)只需要1s。但迷宫是不透光的,而且,要烧掉迷宫的墙也不容易,所以哈利决定绕到一个能够看到奖杯的地方。现在,哈利希望你能帮他确定最短需要多长时间才能拿到奖杯。

输入格式

第一行为2个数N,M表示迷宫的规模(N为高,M为宽)
接下来是N*M的迷宫,O表示空地,X表示墙。
最后是多对数据,分别是奖杯坐标及哈利的坐标(显然不可能在墙上),每对占一行,0为结束标志。

输出格式

根据每对数据,计算哈利拿到奖杯的最短时间,每对一行。如果魔法部有意难为选手,用墙将奖杯包围了起来,输出”Poor Harry”。

输入样例

3 4
OXXO
XXOO
XOOO
3 2 2 4
3 3 1 1
0 0 0 0

输出样例

1
Poor Harry

题解

这题怎么做呢

在这里插入图片描述第一步雀氏纸尿布
利用一维数组存二维数组(a[i][j]存进x[(i-1)n+j])
第二步
处理出所有能看到终点的点并标记

第三步
标准bfs,不过终点不止一个而已
上代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
int n,m;
#define f(i,j) (i-1)*m+j
bool ans[20001];
bool a[20001];
bool vis[20001];
int qi[8]={0,0,-1,1,-1,-1,1,1};
int qj[8]={-1,1,0,0,1,-1,1,-1};
int si,sj,ei,ej;
void pre(){
	int xx,yy;
	for(int e=0;e<8;e++){
		xx=ei;
		yy=ej;
		do{
			ans[f(xx,yy)]=1;
			xx+=qi[e];
			yy+=qj[e];
			if(!(xx>0&&xx<=n&&yy>0&&yy<=m)){
				break;
			}
		}while(!a[f(xx,yy)]);
	}
	return ;
}
struct p{
	int i,j,step;
	p(int _i=0,int _j=0,int s=0){
		i=_i,j=_j,step=s;
	}
};
queue<p> x;
void work(){
	while(!x.empty())x.pop();
	x.push(p(si,sj,0));
	int tti,ttj;
	while(!x.empty()){
		p t=x.front();
		x.pop();
		if(ans[f(t.i,t.j)]){
			cout<<t.step;
			return ;
		}else{
			for(int e=0;e<4;e++){
				tti=t.i+qi[e];
				ttj=t.j+qj[e];
				if(tti>0&&tti<=n&&ttj>0&&ttj<=m&&!a[f(tti,ttj)]&&!vis[f(tti,ttj)]){
					vis[f(tti,ttj)]=1;
					x.push(p(tti,ttj,t.step+1));
				}	
			}
		}
	}
	cout<<"Poor Harry";
	return ;
}
int main(){
//	freopen("jiu.in","r",stdin);
//	freopen("jiu.out","w",stdout);
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			char x;
			cin>>x;
			a[f(i,j)]=(x=='X');
		}
	}
	while(1){
		cin>>ei>>ej>>si>>sj;
		memset(ans,0,sizeof(ans));
		memset(vis,0,sizeof(vis));
		if(!(si||sj||ei||ej)){
			return 0;
		}else{
			pre();
			work();
			cout<<endl;
		}
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/dev_cao/article/details/102710999