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