http://acm.hdu.edu.cn/showproblem.php?pid=4375
网上还很少有人写这道题目的结题报告的,就把我自己能理解的写下来,我是看到 http://www.mzry1992.com/blog/miao/2012-multi-university-training-contest-8.html 博客才慢慢理解的。写的很好,Orz
首先通过分析:
1) 向前走时不能够改变方向的,所以对于题目所给出的指令的某个位置是方向是确定的
2)某个点坐标(x,y)有东南西北四个状态,如果才能表示每个状态的好与坏呢?注意到:一个点在某一时刻处于某种方向,一定比其后还是在改点处于这种方向时更优,因为只要机器人不向前行走,就一定能达到后面的状态。从而我们就能找到状态的优劣,dist[x][y][dir] 表示在(x,y)面向dir方向的最近的指令,bfs即可
3)优化:每个点的状态到另外个状态,有两种方式: 1 前进 ; 2 原地改变方向 具体看代码实现吧!
#include <iostream> #include <algorithm> #include <cstdio> #include <cstring> #include <vector> using namespace std; char s[1000100],mp[1100][1100]; int n,m,l,sx,sy,ex,ey,next[1000100][4],pos[4],dir[1000100],dist[1100][1100][4]; const int step[4][2] = {{-1,0},{0,1},{1,0},{0,-1}}; /* 0 3 1 2 */ vector<pair<int,int> > Q[1000100]; bool BFS() { for (int i = 0;i <= l;i++) Q[i].clear(); for (int i = 0;i < n;i++) for (int j = 0;j < m;j++) for (int k = 0;k < 4;k++) dist[i][j][k] = 2*l; Q[0].push_back(make_pair(sx,sy)); dist[sx][sy][0] = 0; for (int dis = 0;dis <= l;dis++) for (int pi = 0;pi < Q[dis].size();pi++) { pair<int,int> now = Q[dis][pi]; if (now.first == ex && now.second == ey) return true; for (int i = 0;i < 4;i++) if (next[dis][i] != -1) { if (dist[now.first][now.second][i] == 2*l) { dist[now.first][now.second][i] = next[dis][i]; Q[next[dis][i]].push_back(now); } } int v = dir[dis]; pair<int,int> nxt = make_pair(now.first+step[v][0],now.second+step[v][1]); if (nxt.first < 0 || nxt.first >= n || nxt.second < 0 || nxt.second >= m || mp[nxt.first][nxt.second] == '#') continue; if (dist[nxt.first][nxt.second][v] == 2*l) { dist[nxt.first][nxt.second][v] = dis; Q[dis].push_back(nxt); } } return false; } void calcnext() { dir[0] = 0; for (int i = 1;i <= l;i++) if (s[i-1] == 'L') dir[i] = (dir[i-1]+3)%4; else dir[i] = (dir[i-1]+1)%4; for (int i = 0;i < 4;i++) pos[i] = -1; pos[dir[l]] = l; for (int i = l-1;i >= 0;i--) { pos[dir[i]] = i; // next[i][0] = pos[(dir[i]+3)%4]; // next[i][1] = pos[(dir[i]+1)%4]; for(int j=0;j<4;j++) next[i][j]=pos[j]; } } int main() { //freopen("1006.in","r",stdin); // freopen("1006_2.out","w",stdout); while (scanf("%d%d%d",&n,&m,&l) != EOF) { scanf("%s",s); calcnext(); for (int i = 0; i < n; i++) { scanf("%s",mp[i]); for (int j = 0; j < m; j++) if (mp[i][j] == 'S') sx = i,sy = j; else if (mp[i][j] == 'E') ex = i,ey = j; } if (BFS()) puts("Yes"); else puts("No"); } return 0; }