zoukankan      html  css  js  c++  java
  • 网格中的BFS,逆向(POJ2049)

    题目链接:http://poj.org/problem?id=2049

    解题报告:

    网格中的BFS,最主要的是边界问题。

    1、这里在左右,上下两个方向上,分别判断墙,和门,细节是,向上有t个墙,for(int j=0;j<t;j++) ya[x][y+1+j]=WALL;   ymax=max(y+t+1,ymax);xmax=max(x+1,xmax);

    2、这里采用的是逆向BFS,从dis[1][1]出发,输出dis[tx][ty];

    #include <iostream>
    #include <queue>
    #include <stdio.h>
    #include <string.h>
    
    using namespace std;
    
    #define MAXV 210
    #define INF 1<<29
    #define min(a,b) (a>b?b:a)
    #define max(a,b) (a>b?a:b)
    
    #define EMPTY 0
    #define DOOR 1
    #define WALL INF
    
    int xa[MAXV][MAXV];     ///在x方向上添上墙
    int ya[MAXV][MAXV];     ///在y方向上添上墙
    
    int dis[MAXV][MAXV];    ///目标答案,dis[i][j]先初始化为无穷,然后置dis[1][1]为0,
                            ///根据x,y方向上的是否有墙,自增,没有墙置+0,有门+1,dis[tx][ty]也就是答案
    
    int dt[4][2]= {{-1,0},{1,0},{0,-1},{0,1}};      ///四个方向分别是向上,向下,向左,向右
    
    int xmax,ymax;          ///x,y方向上的边界
    
    ///判断是否在图表中
    bool pd(int x,int y)
    {
        if(x>0 && x<=xmax && y<=ymax && y>0) 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);      ///tmp为这个格子是否为墙,门,什么都没有,分别对应inf,1,0
                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(scanf("%d%d",&m,&n))
        {
            ///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++)
            {
                scanf("%d%d%d%d",&x,&y,&d,&t);
                if(d)   ///向上有墙
                {
                    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++)
            {
                scanf("%d%d%d",&x,&y,&d);
                if(d) ya[x][y+1]=DOOR;
                else xa[x+1][y]=DOOR;
            }
    
            scanf("%lf%lf",&sx,&sy);
            if(!(sx>=1 && sx<=199 && sy>=1 && sy<=199)) printf("0
    ");
            else printf("%d
    ",bfs((int)sx+1,(int)sy+1));
        }
        return 0;
    }
    View Code

    参考:http://blog.csdn.net/wangjian8006/article/details/7997609

  • 相关阅读:
    Leetcode Reverse Words in a String
    topcoder SRM 619 DIV2 GoodCompanyDivTwo
    topcoder SRM 618 DIV2 MovingRooksDiv2
    topcoder SRM 618 DIV2 WritingWords
    topcoder SRM 618 DIV2 LongWordsDiv2
    Zepto Code Rush 2014 A. Feed with Candy
    Zepto Code Rush 2014 B
    Codeforces Round #245 (Div. 2) B
    Codeforces Round #245 (Div. 2) A
    Codeforces Round #247 (Div. 2) B
  • 原文地址:https://www.cnblogs.com/TreeDream/p/5392655.html
Copyright © 2011-2022 走看看