SDACM训练赛 3 http://acm.hust.edu.cn/vjudge/contest/view.action?cid=45534#overview
题目链接:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2325
【题意】
给定W*H的迷宫里,给定起点S和终点G,给定N个turn序列(L或者R),要求必须按照这个序列转弯。问能不能到达。
【分析】
比较经典的迷宫最短路问题,这里的序列和费用是turn,转化一下dis【x】【y】 = t 表示走到(x,y)这个格子,用到了turn序列中最小的t位置。然后走到下一步的时候,需要考虑4个方向,预处理cost【t】【k】转入下一个格子。SPFA迭代即可。数据较大,使用STL里的队列模拟。
cost[i][k] = (k==dir[i])?0 : cost[+1][k]+1;初始cost[n][k] = (k==dir[n])?0 : inf;
P.S 比赛的时候没仔细想这个题目,去搞了大坑B题。真是失误。还是得多分析分析题目性质,挖掘出内涵。
1 #include<stdio.h> 2 #include<string.h> 3 #include<math.h> 4 #include<algorithm> 5 #include <queue> 6 using namespace std; 7 8 const int maxn = 1010; 9 const int inf = (1<<30); 10 int W,H,N; 11 12 char mp[maxn][maxn]; 13 char str[maxn*maxn]; 14 int dir[maxn*maxn]; 15 16 int dx[4] = {-1,0,1,0}; 17 int dy[4] = {0,1,0,-1}; 18 19 20 int cost[maxn*maxn][4]; 21 int dis[maxn][maxn]; 22 bool vis[maxn][maxn]; 23 24 struct node{ 25 int x, y; 26 void init(int __x,int __y) 27 { 28 x = __x;y = __y; 29 } 30 }; 31 32 int Sx,Sy; 33 int Gx,Gy; 34 35 queue<node>Q; 36 int main() 37 { 38 while (scanf("%d%d%d",&W,&H,&N)==3 && W) 39 { 40 scanf("%s",str); 41 42 43 dir[0] = 0; 44 for (int i=1;i<=N;i++) 45 { 46 if (str[i-1]=='L'){ 47 dir[i] = (dir[i-1] + 3) % 4; 48 }else{ 49 dir[i] = (dir[i-1] + 1) % 4; 50 } 51 } 52 53 54 for (int i=0;i<=W+1;i++) 55 { 56 for (int j=0;j<=H+1;j++) 57 { 58 mp[i][j] = '#'; 59 } 60 } 61 for (int i=1;i<=W;i++) 62 { 63 scanf("%s",str); 64 for (int j=1;j<=H;j++) 65 { 66 mp[i][j] = str[j-1]; 67 if (mp[i][j]=='S') 68 { 69 Sx = i; 70 Sy = j; 71 mp[i][j] = '.'; 72 }else if (mp[i][j]=='G'){ 73 Gx = i;Gy = j; 74 mp[i][j] = '.'; 75 } 76 } 77 } 78 #ifdef debug 79 for (int i=0;i<=W+1;i++) 80 { 81 for (int j=0;j<=H+1;j++) 82 { 83 printf("%c",mp[i][j]); 84 } 85 puts(""); 86 } 87 printf("%d %d %d %d\n",Sx,Sy,Gx,Gy); 88 #endif 89 90 for (int i=N;i>=0;i--) 91 { 92 for (int j=0;j<4;j++) 93 { 94 if (dir[i]==j){ 95 cost[i][j] = 0; 96 }else{ 97 if (i==N){ 98 cost[i][j] = inf; 99 }else{ 100 cost[i][j] = cost[i+1][j] + 1; 101 } 102 } 103 //if (debug)printf("%d %d %d\n",i,j,cost[i][j]); 104 } 105 } 106 107 node now, cur; 108 int ans = 0; 109 memset(dis, -1, sizeof(dis)); 110 memset(vis, 0, sizeof(vis)); 111 now.init(Sx,Sy); 112 dis[Sx][Sy] = 0; 113 vis[Sx][Sy] = 1; 114 while (!Q.empty()) 115 { 116 Q.pop(); 117 } 118 Q.push(now); 119 while (!Q.empty()) 120 { 121 cur = Q.front(); 122 Q.pop(); 123 int dd = dis[cur.x][cur.y]; 124 vis[cur.x][cur.y] = 0; 125 for (int k=0;k<4;k++) 126 { 127 int x = cur.x + dx[k]; 128 int y = cur.y + dy[k]; 129 if (mp[x][y]=='.' && cost[dd][k]<inf){ 130 int tmp = dd + cost[dd][k]; 131 if (dis[x][y]==-1 || tmp < dis[x][y]){ 132 dis[x][y] = tmp; 133 if (x == Gx && y == Gy) 134 { 135 ans = 1; 136 break; 137 } 138 if (!vis[x][y]){ 139 now.init(x,y); 140 Q.push(now); 141 vis[x][y] = 1; 142 } 143 } 144 } 145 } 146 } 147 // ans = (dis[Gx][Gy] != -1); 148 puts(ans?"Yes":"No"); 149 } 150 return 0; 151 }