某周日,回寝室路上,让室友帮忙找个东西,室友问找啥,答曰:Nemo。
1、百练上只有不到一半的通过率还是有点恐怖的,这道题让nemo他爹找nemo,让我想到之前的走迷宫,于是想到用广度优先搜索的办法,只不过把原来的queue改成了priority——queue,让走过的doors数量最少的借点排在最前面,这样第一个走出迷宫范围的结点就一定最优解(我是每次从队列中取出元素之后再判断是否在迷宫外面,而不是在搜索的时候直接进行判断,后者的方法应该是错误的)。
2、坑点在于nemo的初始位置可以是在迷宫外面的,因此在最刚开始入队的时候要先进行一次判断,如果在迷宫外面直接输出0即可。
3、另外卡了我将近一个小时的点在于priority_queue的数据排列顺序,top()的元素是最大的一个元素!也就是说我们在对运算符进行重载的时候要把符号正好反过来!记忆的方法是权重最大的符号要在最前面!
4、这道题也可以当作图的题目来做,把整个迷宫看作一个图,如果两个节点之间是门,距离就视为1,没有门距离就视为1,有墙壁则没有通路,只是一个想法,不知道有哪位大神可以实现,感觉这道题放在图的图题目里面还是很坑爹的。
#include<iostream>
#include<limits.h>
#include<memory.h>
#include<cstdio>
#include<cstring>
#include<memory.h>
#include<queue>
using namespace std;
#define maxn 220
struct maze_node{
bool uw,rw;
bool ud,rd;
};
struct node{
float x,y;
int doors;
};
bool operator < (node a,node b){
return a.doors > b.doors;
}
maze_node maze[maxn][maxn] ={0};
bool used[maxn][maxn]={0};
bool init(){
memset(used,0,sizeof(used));
memset(maze,0,sizeof(maze));
int W,D;
int x,y,dir,len;
scanf("%d%d",&W,&D);
if(W==-1&&D==-1)
return false;
while(W--){
scanf("%d%d%d%d",&x,&y,&dir,&len);
if(dir){
for(int i=0;i<len;++i){
maze[x][y+i].uw = 1;
}
}
else{
for(int i=0;i<len;++i){
maze[x+i][y].rw = 1;
}
}
}
while(D--){
scanf("%d%d%d",&x,&y,&dir);
if(dir){
maze[x][y].ud = 1;
maze[x][y].uw = 0;
}
else{
maze[x][y].rd = 1;
maze[x][y].rw = 0;
}
}
return true;
}
int main(){
while(init()){
float _x,_y;
cin>>_x>>_y;
if(_x<1.0||_x >199.0||_y<1.0||_y>199.0){
cout<<0<<endl;
continue;
}
node temp;
temp.x = _x;
temp.y = _y;
temp.doors = 0;
priority_queue<node> q;
used[int(_x)][int(_y)] = 1;
q.push(temp);
bool find = false;
while(q.size()){
temp = q.top();
q.pop();
//cout<<temp.x<<' '<<temp.y<<endl;
if(temp.x<1.0||temp.x>199.0||temp.y<1.0||temp.y>199.0){
find = true;
break;
}
int ix = (int)temp.x;
int iy = (int)temp.y;
used[ix][iy] = 1;
if(!maze[ix][iy].uw && !used[ix-1][iy]){
int td = temp.doors;
if(maze[ix][iy].ud)
td++;
node ins;
ins.x = temp.x-1.0;
ins.y = temp.y;
ins.doors = td;
q.push(ins);
}
if(!maze[ix][iy].rw && !used[ix][iy-1]){
int td = temp.doors;
if(maze[ix][iy].rd)
td++;
node ins;
ins.x = temp.x;
ins.y = temp.y-1.0;
ins.doors = td;
q.push(ins);
}
if(!maze[ix+1][iy].uw && !used[ix+1][iy]){
int td = temp.doors;
if(maze[ix+1][iy].ud)
td++;
node ins;
ins.x = temp.x+1.0;
ins.y = temp.y;
ins.doors = td;
q.push(ins);
}
if(!maze[ix][iy+1].rw && !used[ix][iy+1]){
int td = temp.doors;
if(maze[ix][iy+1].rd)
td++;
node ins;
ins.x = temp.x;
ins.y = temp.y+1.0;
ins.doors = td;
q.push(ins);
}
}
if(find){
cout<<temp.doors<<endl;
}
else{
cout<<"-1"<<endl;
}
}
//system("pause");
return 0;
}