POJ 2049

题目大意,在迷宫中找一条出口,题目的本质其实是 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], 这个点是搜寻的起点。

其他应该没有什么问题。

你可能感兴趣的:(C++,算法,搜索,poj)