HDU 4375 Programmable Robot 预处理 + bfs

来源:互联网 发布:淘宝管制刀具定义 编辑:程序博客网 时间:2024/05/16 06:44

题目大意:

就是现在有一个H*W的地图, H, W <= 1000, 要从S的位置到E的位置, 每次进行的操作要么是向左或者右转, 要么是向前走, 现在给出一个只有旋转的序列(只有L, R, 没有向前走的F), 现在在这个序列的任意位置加入任意数量的F问是否可以成为一个从S到达E的指令序列


大致思路:

考虑到到达位置(x, y)面朝方向为d的序列一定是在那个LR位置尽量靠前的位置更优, bfs的时候的状态只有H*W*4种

那么处理出每个LR序列的位置i到下一次面朝位置为d的对应LR序列位置为next[i][d]即可


代码如下:

Result  :  Accepted     Memory  :  86780 KB     Time  :  951 ms

/* * Author: Gatevin * Created Time:  2015/8/10 13:48:42 * File Name: Sakura_Chiyo.cpp */#include<iostream>#include<sstream>#include<fstream>#include<vector>#include<list>#include<deque>#include<queue>#include<stack>#include<map>#include<set>#include<bitset>#include<algorithm>#include<cstdio>#include<cstdlib>#include<cstring>#include<cctype>#include<cmath>#include<ctime>#include<iomanip>using namespace std;const double eps(1e-8);typedef long long lint;/* * 考虑到对于到达位置(x, y)朝向为d, 到达当前序列为第k个的情况, 一定比(x, y, d)且k2 > k的情况要优 * 所以在惊醒bfs的时候要遍历的状态只有[x][y][d]一共H*W*4种 * 由于优的是k2 > k的情况需要按照给出的LR的序列从前向后来进行bfs * 这里我图方便直接开了N个队列MLE了...于是换了邻接表来存储... * 为了转移的方便需要处理出对于给出的LR的序列当前在第i个, 要转到面朝特定方向时接下来需要转到序列中的哪个L或R才能行 */int dx[] = {-1, 0, 1, 0};int dy[] = {0, 1, 0, -1};int H, W, N;#define next nexchar lr[1000100];//int next[1000100][4];int dir[1000100];const int inf = 1e9 + 7;char maz[1010][1010];int vis[1010][1010][4];int sx, sy, ex, ey;#define mp make_pairint cas;int tot;//邻接表边数struct Edge//queue MLE了换邻接表上{    int x, y, nex;};Edge edge[4000010];int head[1000010];void addEdge(int s, int x, int y){    edge[tot].x = x, edge[tot].y = y;    edge[tot].nex = head[s];    head[s] = tot++;}bool bfs(){    //Q[0].push(mp(sx, sy));    memset(head, -1, sizeof(head));    tot = 0;    while(sx >= 0 && sx < H && sy >= 0 && sy < W && vis[sx][sy][0] != cas && maz[sx][sy] != '#')    {        //Q[0].push(mp(sx, sy));        addEdge(0, sx, sy);        vis[sx][sy][0] = cas;        if(sx == ex && sy == ey) return true;        sx += dx[0], sy += dy[0];    }    for(int i = 0; i <= N; i++)    {        //while(!Q[i].empty())        for(int j = head[i]; j + 1; j = edge[j].nex)        {            //int nx = Q[i].front().first, ny = Q[i].front().second;            int nx = edge[j].x, ny = edge[j].y;            //Q[i].pop();            for(int d = 0; d < 4; d++)            {                if(next[i][d] == inf) continue;                int tx = nx + dx[d], ty = ny + dy[d];                while(tx >= 0 && tx < H && ty >= 0 && ty < W && vis[tx][ty][d] != cas && maz[tx][ty] != '#')                {                    //Q[next[i][d]].push(mp(tx, ty));                    addEdge(next[i][d], tx, ty);                    vis[tx][ty][d] = cas;                    if(tx == ex && ty == ey) return true;                    tx += dx[d], ty += dy[d];                }            }        }    }    return false;}void init(){    dir[0] = 0;    for(int i = 0; i < N; i++)        dir[i + 1] = (lr[i] == 'L') ? (dir[i] + 3) % 4 : (dir[i] + 1) % 4;    int last[4] = {inf, inf, inf, inf};    for(int i = N; i >= 0; i--)    {        for(int j = 0; j < 4; j++)            next[i][j] = last[j];        last[dir[i]] = i;    }    return;}int main(){    cas = 0;    memset(vis, 0, sizeof(vis));    while(~scanf("%d %d %d", &H, &W, &N))    {        cas++;        scanf("%s", lr);        init();        for(int i = 0; i < H; i++)        {            scanf("%s", maz[i]);            for(int j = 0; j < W; j++)                if(maz[i][j] == 'S') sx = i, sy = j;                else if(maz[i][j] == 'E') ex = i, ey = j;        }        if(bfs()) puts("Yes");        else puts("No");    }    return 0;}


0 0