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暴力出答案的。

每个点记录四个方向的最少操作,再记录到这个点的这个方向有多少种不同的方向。

View Code
#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;
}

posted on 2012-10-08 12:07  aigoruan  阅读(188)  评论(0)    收藏  举报

导航