483: qtech系列故事之——北京奇遇记
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 32 Solved: 3
[ Submit][ Status][ Web Board]
Description
在美丽的qtech,有一个传奇的人物,被叫做671coder,大家都亲切的称呼他为“耀哥”。耀哥现在大四了,作为一个ACMer,大学期间是木有什么项目经验的,所以耀哥就一直在苦逼寒酸的找工作。。。
一天耀哥在去北邮的路上,看到了一个瓶子,耀哥心想:垃圾怎么能随地乱扔呢,于是就捡了起来。拿起来之后,发现这个瓶盖子很独特,便打开了看看。谁知道!这一打开不要紧!眼前突然出现了一个巨人!巨人说:“我是瓶子神,我可以给你一个迷宫,给你一个限定时间,如果你能在规定时间恰好走到指定终点,我就会给你一个年薪100w的offer,如果你感觉我给你的迷宫不能在规定时间恰好走到终点,你可以选择找我换一个迷宫,当然,只要你决定了就无法更改。”(当然由于耀哥腿脚不是太灵便,1s只能走一格)
耀哥想了想:自己好歹大学期间也是搞acm的,迷宫什么的能难道我么?于是他淡定的说:“来吧!迷宫拿来!”于是巨人就把迷宫给了耀哥。
聪明的你,作为一个ACMer,请帮耀哥计算一下他是需要找巨人换迷宫呢?还是勇敢的走下去这个迷宫呢?
Input
输入第一行包含三个数据N,M,T, N代表迷宫的长度;M代表迷宫的宽度;T代表给的规定时间。当N、M、T都为0的时候输入结束。(1 < N, M < 7; 0 < T < 50)
接下来就是一个迷宫,’S’表示耀哥的起始位置;’D’表示迷宫的出口;’.’表示这里是空地,可以走;’X’则表示这里是墙,不能经过。
Output
如果耀哥能在限定时间内,顺利走到终点,请输出”Get it!”,否则需要找到巨人换,请输出”Change it!”。
Sample Input
Sample Output
#include<cstdio>
#include<iostream>
#include<queue>
#include<algorithm>
#include<string.h>
#include<stdlib.h>
using namespace std;
#define MAX_SIZE 50 + 10
/*多状态的BFS统计*/
int visa[MAX_SIZE][MAX_SIZE][4][55];
int dist[MAX_SIZE][MAX_SIZE][4];/*表示在x,y坐标方向为z的是否被遍历过*/
int N,M,T;
int dir1[4]={1,-1,0,0};
int dir2[4]={0,0,-1,1};
int start_x,start_y;
int end_x,end_y;
char maps[MAX_SIZE][MAX_SIZE];
struct step /*这个表示每一个点的状态*/{
int x;
int y;
int dist;/*表示从起点走到这一步花的歩数*/
friend bool operator < (const step &a, const step &b){ // 重载<构建最小堆
return a.dist > b.dist;
}
};
struct step start,p1,p2;
void find_start_end()
{
int ok1=0;
int ok2=0;
for(int i=0;i<N;i++){
for(int j=0;j<M;j++){
if(maps[i][j]=='S'){
start_x=i;
start_y=j;
}
if(maps[i][j]=='D'){
end_x=i;
end_y=j;
}
if(ok1&&ok2) return;
}
}
}
void dfs()
{
priority_queue<step>S;
int ok=1;
while(!S.empty())
S.pop();
/*初始化*/
start.x=start_x;
start.y=start_y;
start.dist=0;
/*初始化起点*/
S.push(start);/*加入到队列里面*/
while(!S.empty())
{
int nx,ny;
p1=S.top();/*从顶部拿取元素*/
S.pop();
//printf("(%d,%d,%d)\n",p1.x,p1.y,p1.dist);
for(int i=0;i<4;i++)
{
nx=p1.x+dir1[i];
ny=p1.y+dir2[i];
/*如果这个点没有越界并且是一个可走路
并且方向没有走过*/
if((nx>=0&&ny>=0&&nx<N&&ny<M&&!visa[nx][ny][i][p1.dist+1]&&maps[nx][ny]!='X'))
{
visa[nx][ny][i][p1.dist+1]=1;
p2.x=nx;
p2.y=ny;
dist[nx][ny][i]=p1.dist+1;
p2.dist=dist[nx][ny][i];
//printf("(%d %d %d)->(%d,%d,%d)\n",p1.x,p1.y,p1.dist,p2.x,p2.y,p2.dist);
S.push(p2);
if(nx==end_x&&ny==end_y&&p2.dist==T)
{
printf("Get it!\n");
ok=0;
break;
}
}
}
if(!ok) break;
}
if(ok)
printf("Change it!\n");
}
int main(){
for(;scanf("%d%d%d%*c",&N,&M,&T);){
memset(visa,0,sizeof(visa));
memset(dist,0,sizeof(dist));
if(!N&&!M&&!T) break;
for(int i=0;i<N;i++)/*输入迷宫!*/
gets(maps[i]);
find_start_end();
/*找到迷宫的起始和结束点*/
dfs();
/*开始进行遍历*/
}
return 0;
}