[HDU] 4528 小明系列故事——捉迷藏 又一个需要靠多维变量来记录一个状态访问没有被访问的广搜题

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=4528

方法:地图输入接收完成后,扫面数组,把所有可以看到D和E的位置都标记了,d表示可以看到D,e表示可以看到E,b表示两个都可以看到,这一步放在广搜前的初始化里面。在广搜时,树中的每一个状态节点有3个信息,图中坐标x y,到当前有没有已经看到D getD,到当前有没有已经看到E getE,和当前使用的时间。探寻到一个状态节点,将不将其放入优先队列,从不从该节点开始广搜判断的依据为改状态所处位子是不是墙或D或E(题目要求不能穿过D或E)已经该状态有没有搜索过。判断一个状态有没有搜索过,主要由一个4维变量来记录其访问情况,即用v[x][y][getD][getE]来表示。

除此之外,由于题目要求有时间限制,所以可以用当前使用的时间来剪枝。

感想:重点在于模拟。

代码:

View Code
#include <iostream>
#include <queue>
using namespace std;
int n,m,timeLimit;
int Dx,Dy,Ex,Ey,Sx,Sy;
char map[102][102];
bool v[102][102][2][2];
char start = 'S';
char D ='D';
char E ='E';
char canGetD = 'd';
char canGetE = 'e';
char canGetBoth='b';
char wall = 'X';
char road = '.';
int deriction[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
struct Location
{
    int x,y;
    int time;
    bool getD;
    bool getE;
};
struct cmp
{
    bool operator()(Location x,Location y)
    {
        if(x.time>y.time)
            return true;
        return false;
    }
};
bool canGo(int x,int y,bool canGetD,bool canGetE)
{
    return map[x][y]!=wall && map[x][y]!=D && map[x][y]!=E && !v[x][y][canGetD][canGetE];
}
void initialize()
{
    int t_x=Dx,t_y=Dy;
    while(map[t_x+1][t_y]!=wall && map[t_x+1][t_y]!=E)
    {
            if(map[t_x+1][t_y]==road || map[t_x+1][t_y]==start)
                map[t_x+1][t_y] =canGetD;
            else 
                map[t_x+1][t_y] = canGetBoth;
        t_x++;
    }
    t_x=Dx,t_y=Dy;
    while(map[t_x-1][t_y]!=wall && map[t_x-1][t_y]!=E)
    {
            if(map[t_x-1][t_y]==road || map[t_x-1][t_y]==start)
                map[t_x-1][t_y] = canGetD;
            else 
                map[t_x-1][t_y] = canGetBoth;
        t_x--;
    }
    t_x=Dx,t_y=Dy;
    while(map[t_x][t_y+1]!=wall && map[t_x][t_y+1]!=E)
    {
            if(map[t_x][t_y+1]==road || map[t_x][t_y+1]==start)
                map[t_x][t_y+1] = canGetD;
            else 
                map[t_x][t_y+1] = canGetBoth;
        t_y++;
    }
    t_x=Dx,t_y=Dy;
    while(map[t_x][t_y-1]!=wall && map[t_x][t_y-1]!=E)
    {
            if(map[t_x][t_y-1]==road || map[t_x][t_y-1]==start)
                map[t_x][t_y-1] = canGetD;
            else 
                map[t_x][t_y-1] = canGetBoth;
        t_y--;
    }

    t_x=Ex,t_y=Ey;
    while(map[t_x+1][t_y]!=wall && map[t_x+1][t_y]!=D)
    {
            if(map[t_x+1][t_y]==road || map[t_x+1][t_y]==start)
                map[t_x+1][t_y] = canGetE;
            else 
                map[t_x+1][t_y] = canGetBoth;
        t_x++;
    }
    t_x=Ex,t_y=Ey;
    while(map[t_x-1][t_y]!=wall  &&map[t_x-1][t_y]!=D )
    {
            if(map[t_x-1][t_y]==road || map[t_x-1][t_y]==start)
                map[t_x-1][t_y] = canGetE;
            else 
                map[t_x-1][t_y] = canGetBoth;
        t_x--;
    }
    t_x=Ex,t_y=Ey;
    while(map[t_x][t_y+1]!=wall  &&map[t_x][t_y+1]!=D )
    {
            if(map[t_x][t_y+1]==road || map[t_x][t_y+1]==start)
                map[t_x][t_y+1] = canGetE;
            else 
                map[t_x][t_y+1] = canGetBoth;
        t_y++;
    }
    t_x=Ex,t_y=Ey;
    while(map[t_x][t_y-1]!=wall  && map[t_x][t_y-1]!=D )
    {
            if(map[t_x][t_y-1]==road || map[t_x][t_y-1]==start)
                map[t_x][t_y-1] = canGetE;
            else 
                map[t_x][t_y-1] = canGetBoth;
        t_y--;
    }
}
int BFSearch()
{
    initialize();
    Location startLocation;
    startLocation.x = Sx;
    startLocation.y = Sy;
    startLocation.time = 0;
    startLocation.getD = map[startLocation.x][startLocation.y] ==canGetD ||map[startLocation.x][startLocation.y] == canGetBoth;
    startLocation.getE = map[startLocation.x][startLocation.y] ==canGetE ||map[startLocation.x][startLocation.y] == canGetBoth;
    priority_queue<Location,vector<Location>,cmp> q;
    q.push(startLocation);
    while(!q.empty())
    {
        Location t_location = q.top();
        q.pop();
        if(t_location.getD && t_location.getE)
            return t_location.time;
        else
        {
            if(!v[t_location.x][t_location.y][t_location.getD][t_location.getE])
            {
                v[t_location.x][t_location.y][t_location.getD][t_location.getE]= true;
                int n_x,n_y;
                bool n_getD,n_getE;
                Location n_location;
                for(int i=0;i<4;i++)
                {
                    n_x = t_location.x + deriction[i][0];
                    n_y = t_location.y + deriction[i][1];
                    n_getD = map[n_x][n_y] ==canGetD || t_location.getD|| map[n_x][n_y] == canGetBoth;
                    n_getE = map[n_x][n_y] ==canGetE || t_location.getE|| map[n_x][n_y] == canGetBoth;
                    if(canGo(n_x,n_y,n_getD,n_getE) && t_location.time+1<=timeLimit)
                    {
                        n_location.x = n_x;
                        n_location.y = n_y;
                        n_location.time = t_location.time+1;
                        n_location.getD = n_getD;
                        n_location.getE =n_getE;
                        q.push(n_location);
                    }
                }
            }
        }
    }
    return -1;
}
 
void main()
{
    int tc=0,t;
    scanf("%d",&t);
    while(tc<t)
    {
        memset(map,'X',sizeof(map));
        memset(v,false,sizeof(v));
        scanf("%*c %d %d %d",&n,&m,&timeLimit);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
            {
                cin>>map[i][j];
                if(map[i][j] ==D)
                {
                    Dx = i;
                    Dy = j;
                }
                if(map[i][j] == E)
                {
                    Ex = i;
                    Ey = j;
                }
                if(map[i][j] ==start)
                {
                    Sx = i;
                    Sy = j;
                }
            }
            cout<<"Case "<<tc+1<<":"<<endl<<BFSearch()<<endl;
        tc++;
    }
}
原文地址:https://www.cnblogs.com/kbyd/p/3029213.html