题目大意,在迷宫中找一条出口,题目的本质其实是 BFS+ 优先队列实现
这里说一下,建立图模型,在坐标轴上的原点对应于网格的(1,1)点
xa[i][j] 表示的是网格的上边,这边有点难理解,我这里困了一下午。
我画了一个图,右下角是(i,j),那xa[i][j]就表示b ,相应的ya[i][j] 就表示a
图好像显示不出来,大致就是这样: 一个正方形左下角定为(i,j), 正方形最上面的边为a,最右边的边为b
#include<iostream>
#include<queue>
using namespace std;
#define MAXV 210
#define INF 1<<29
#define Empty 0
#define Door 1
#define Wall INF
#define min(a,b) (a>b?b:a)
#define max(a,b) (a>b?a:b)
int xa[MAXV][MAXV],ya[MAXV][MAXV];
int dis[MAXV][MAXV];
int dt[4][2] = {{-1,0},{1,0},{0,-1},{0,1}};
int xmax,ymax;
bool pd(int x,int y){
if(x>0&&x<=xmax&&y>0&&y<=ymax) return 1;
return 0;
}
int getvalue(int x,int y,int i){
if(i == 0) return ya[x-1][y];
if(i == 1) return ya[x][y];
if(i == 2) return xa[x][y-1];
return xa[x][y];
}
int bfs(int tx,int ty){
int i,j,vx,vy,dx,dy,tmp;
queue<int>q;
for(i=1;i<=ymax;i++){
for(j=1;j<=xmax;j++)
dis[i][j] = INF;
}
dis[1][1] = 0;
q.push(1);
q.push(1);
while(!q.empty()){
vx = q.front(); q.pop();
vy = q.front(); q.pop();
for(i=0;i<4;i++){
dx = vx + dt[i][0];
dy = vy + dt[i][1];
tmp = getvalue(vx,vy,i);
if(pd(dx,dy)&&dis[dx][dy]>dis[vx][vy]+tmp){
dis[dx][dy] = dis[vx][vy] + tmp;
q.push(dx);
q.push(dy);
}
}
}
return (dis[tx][ty] == INF?-1:dis[tx][ty]);
}
int main(){
int n,m,i,j;
int x,y,d,t;
double sx,sy;
while(cin>>m>>n){
if(m==-1&&n==-1) break;
ymax = xmax = -1;
memset(xa,Empty,sizeof(xa));
memset(ya,Empty,sizeof(ya));
for(i=0;i<m;i++){
cin>>x>>y>>d>>t;
if(d == 1){
for(j=0;j<t;j++)
ya[x][y+j+1] = Wall;
ymax = max(y+t+1,ymax);
xmax = max(x+1,xmax);
}
else{
for(j=0;j<t;j++)
xa[x+j+1][y] = Wall;
ymax = max(y+1,ymax);
xmax = max(x+t+1,xmax);
}
}
for(i=0;i<n;i++){
cin>>x>>y>>d;
if(d == 1) ya[x][y+1] = Door;
else xa[x+1][y] = Door;
}
cin>>sx>>sy;
if(!(sx>=1&&sx<=199&&sy>=1&&sy<=199))
cout<<0<<endl;
else{
cout<<bfs((int)sx+1,(int)sy+1)<<endl;
}
}
return 0;
}
这道题应该是比较经典的 宽度搜索BFS的题目,其本质是 将符合条件的点都入队,然后对于每个入队的点 再进行分析, 更新dis数组,这样就可以找到一条最优值。
注意,这里的起点应该是 dis[1][1], 这个点是搜寻的起点。
其他应该没有什么问题。