hdu 4230 Robot Navigation
http://acm.hdu.edu.cn/showproblem.php?pid=4230
题意:给一个二维地图,一个机器人有三种操作:1、向前走;2、左转90度;3、右转90度。
现给定起点和终点,问有多少种不同的操作是最少的。
思路:这个题目神似:http://www.cnblogs.com/aigoruan/archive/2012/10/05/2712432.html
正解应该是先弄出最短路径后,再DFS求解答案,但其实可以直接BFS暴力出答案的。
每个点记录四个方向的最少操作,再记录到这个点的这个方向有多少种不同的方向。

#include<stdio.h> #include<string.h> #include<iostream> #include<queue> using namespace std; const int maxn = 105; const int inf = 1<<29; struct nd{ int x,y,d,t,id; }; int has[maxn][maxn][4]; int ans[maxn][maxn][4]; int vis[maxn][maxn][4]; int dx[] = {0,-1,0,1}; int dy[] = {1,0,-1,0}; char as[maxn][maxn],E[10],dd[128]; int N,M,m=1000000,mn,cnt; int si,sj,di,dj; bool nok(int x,int y){ if(x<0||y<0||x==N||y==M||as[x][y]=='*')return true; return false; } void bfs(int x,int y,int d) { nd k,t; int a,b,c,i; cnt = 0; for(a = 0; a < N; ++ a) for(b = 0; b < M; ++ b) for(c = 0; c < 4; ++ c) has[a][b][c]=inf,ans[a][b][c]=0; has[x][y][d]=0; ans[x][y][d]=1; if(x==di&&y==dj)return; queue<nd>que; t.x=x;t.y=y;t.d=d;t.t=0; t.id = cnt; vis[x][y][d]=cnt++; que.push(t); while(!que.empty()){ t = que.front(); que.pop(); if(t.id ^ vis[t.x][t.y][t.d])continue; for(i = 0; i < 4; ++ i){ k = t; k.t++; k.d = i; if(nok(k.x,k.y)||(i+2)%4==t.d)continue; if(k.d==t.d){ k.x += dx[i]; k.y += dy[i]; for(;!nok(k.x,k.y);k.x+=dx[i],k.y+=dy[i]){ if(k.t>has[k.x][k.y][k.d]||k.t>mn)continue; if(k.t==has[k.x][k.y][k.d]){ ans[k.x][k.y][k.d] += ans[t.x][t.y][t.d]; if(ans[k.x][k.y][k.d]>=m)ans[k.x][k.y][k.d]-=m; }else ans[k.x][k.y][k.d]=ans[t.x][t.y][t.d]; has[k.x][k.y][k.d] = k.t; if(k.x==di && k.y==dj){ if(has[k.x][k.y][k.d]<mn)mn=has[k.x][k.y][k.d]; continue; } k.id = cnt; vis[k.x][k.y][k.d] = cnt++; que.push(k); } continue; } if(k.t>has[k.x][k.y][k.d]||k.t>mn)continue; if(k.t==has[k.x][k.y][k.d]){ ans[k.x][k.y][k.d] += ans[t.x][t.y][t.d]; if(ans[k.x][k.y][k.d]>=m)ans[k.x][k.y][k.d]-=m; }else{ ans[k.x][k.y][k.d]=ans[t.x][t.y][t.d]; if(ans[k.x][k.y][k.d]>=m)ans[k.x][k.y][k.d]-=m; } has[k.x][k.y][k.d] = k.t; if(k.x==di && k.y==dj){ if(has[k.x][k.y][k.d]<mn)mn=has[k.x][k.y][k.d]; continue; } k.id = cnt; vis[k.x][k.y][k.d] = cnt++; que.push(k); } ans[t.x][t.y][t.d]=0; } } int main() { int i,k,j; dd['E']=0;dd['N']=1;dd['W']=2;dd['S']=3; while(scanf("%d %d",&N,&M)!=EOF){ if(!M)break; for(i = 0; i < N; ++ i) scanf("%s",as[i]); for(i = 0; i < N; ++ i) for(j = 0; j < M; ++ j) if(as[i][j]=='X'){as[i][j]='.';di=i;dj=j;} else if(as[i][j]!='.'&&as[i][j]!='*'){E[0]=as[i][j];as[i][j]='.';si=i;sj=j;} mn = inf; bfs(si,sj,dd[(int)E[0]]); k = 0; for(i = 0; i < 4; ++ i){ if(has[di][dj][i]<mn){ mn = has[di][dj][i]; k = ans[di][dj][i]; }else if(has[di][dj][i]==mn){ k += ans[di][dj][i]; if(k >= m)k -= m; } } if(mn==inf)mn=k=0; printf("%d %d\n",mn,k); } return 0; }