首页 > ACM题库 > HDU-杭电 > HDU 4375-Programmable Robot[解题报告]HOJ
2015
05-24

HDU 4375-Programmable Robot[解题报告]HOJ

Programmable Robot

问题描述 :

Recently, Soy Ma is taking part in a robot competition. Yesterday, he bought a new kind of programmable robot. He thinks these robots can solve the problem in the maze.
The maze is made up of H × M girds. Each gird is either an empty cell ‘.’ or a wall cell ‘#’. And Soy Ma’s task is to make a program for the robot which can go from START cell ‘S’ to END cell ‘E’ without going into any wall cell.
The robot can receive three kinds of instructions:
1. ’F’: Go forward exactly one cell;
2. ‘L’: Turn left for 90 degrees;
3. ‘R’: Turn right for 90 degrees.
But the competition committee thought it was so easy to solve the problem for such ACMers like Soy Ma and you. Soon they made some additional rules in the competition:
1. The committee will give an standard program for each maze, and the program consists only ‘L’ and ‘R’ instructions;
2. The competitors should only add ‘F’ instructions into the program;
3. The competitors should not change the amount and the order of the ‘L’, ‘R’ instructions.
For example, if the standard program is “LRR”, then the competitor can add ‘F’ instructions in front of ‘L’ to get “FFLRR”, or add after the end of it getting “LRRFFF”, and also “FFLRRF”, “FLFFRFRF”, “LFFFFRRFFF”, etc., but never “RRFL”, “RRF”, “LRFFRR” nor “LLRF”.
Unfortunately, not all standard programs can be adapted to solve the problem for a given maze, and Soy Ma is worrying about that.
So, as a friend of Soy Ma, you want to help him. Now given the maze and the standard program provided by the committee, can you tell Soy Ma whether he can solve the problem?

输入:

There are multiple test cases, process to the end of input.
For each case, the first line contains three integers H, W, N, indicating the height and width of the maze and the length of the standard program (1 ≤ H, W ≤ 1000, 1 ≤ N ≤ 1000000).
The second line contains N characters of ‘L’ and ‘R’ which describes the standard program given by the committee.
Next H lines each contain W characters which describes the maze. A ‘.’ character stands for an empty cell, ‘#’ stands for an wall cell, ‘S’ stands for start cell, ‘E’ stands for end cell. You can assume there is only one ‘S’ character and only one ‘E’ character in each maze.
The robot always faces to the north initially.

输出:

There are multiple test cases, process to the end of input.
For each case, the first line contains three integers H, W, N, indicating the height and width of the maze and the length of the standard program (1 ≤ H, W ≤ 1000, 1 ≤ N ≤ 1000000).
The second line contains N characters of ‘L’ and ‘R’ which describes the standard program given by the committee.
Next H lines each contain W characters which describes the maze. A ‘.’ character stands for an empty cell, ‘#’ stands for an wall cell, ‘S’ stands for start cell, ‘E’ stands for end cell. You can assume there is only one ‘S’ character and only one ‘E’ character in each maze.
The robot always faces to the north initially.

样例输入:

2 2 1
L
E.
.S
2 3 2
RR
E..
..S
3 3 8
LLLLLLLL
E#.
...
##S

样例输出:

Yes
No
Yes

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <queue>

#define N 1010
#define M 1000010

using namespace std;

int sx,sy,ex,ey;
int H,W,n;
int vis[N][N][4];
char str[M];
char st[N];
int map[N][N];
int head[M];
int next[N*N*4];
int x[]={0,1,0,-1};
int y[]={1,0,-1,0};
queue < pair<int,int> > que;

int code(int i,int j,int k){
    return j+i*W+k*H*W;
}
int td[M];
int dir[M][4];
void init(){
    td[0]=3;
    for (int i=0;i<n;i++)
        if (str[i]=='R')
            td[i+1]=(td[i]+1)%4;
        else
            td[i+1]=(td[i]+3)%4;
    int nt[4]={n+1,n+1,n+1,n+1};
    for (int i=n;i>=0;i--){
        copy(nt,nt+4,dir[i]);
        nt[td[i]]=i;
    }
}
void insert(int k,int tx,int ty,int td){
    //printf("%d %d %d %d\n",k,tx,ty,td);
    while (1){
        if (tx<0||ty<0||tx>=H||ty>=W) break;
        if (!map[tx][ty]) break;
        if (vis[tx][ty][td]) break;
        vis[tx][ty][td]=1;
        next[code(tx,ty,td)]=head[k];
        head[k]=code(tx,ty,td);
        tx=tx+x[td];
        ty=ty+y[td];
    }
}
bool bfs(){
    init();
    //for (int i=0;i<4;i++)
    //    printf(" %d",dir[0][i]);
    //printf("\n");
    memset(vis,0,sizeof(vis));
    memset(head,-1,sizeof(head));
    insert(0,sx,sy,3);
    for (int i=0;i<=n;i++)
        for (int j=head[i];j!=-1;j=next[j]){
            int ty=j%W,tx=j/W%H;
            for (int k=0;k<4;k++)
                if (dir[i][k]<=n) insert(dir[i][k],tx,ty,k);
            for (int k=0;k<4;k++)
                if (vis[ex][ey][k]) return 1;
        }
    for (int k=0;k<4;k++)
        if (vis[ex][ey][k]) return 1;
    return 0;
}
int main(){
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    while (scanf("%d%d%d",&H,&W,&n)==3){
        scanf("%s",str);
        //printf("%d %d %d\n",H,W,n);
        //printf("%s\n",str);
        int i,j;
        memset(map,0,sizeof(map));
        for (i=0;i<H;i++){
            scanf("%s",st);
            for (j=0;j<W;j++)
                if (st[j]=='.') map[i][j]=1;
                else if (st[j]=='S') {sx=i;sy=j;map[i][j]=1;}
                else if (st[j]=='E') {ex=i;ey=j;map[i][j]=1;}
        }
        if (bfs()) printf("Yes\n");
        else printf("No\n");
    }
    return 0;
}