首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

hdu4230 Robot Navigation 迷宫最短路径的条数 BFS 很强横!

2012-07-30 
hdu4230Robot Navigation迷宫最短路径的条数 BFS 很霸气!!!!!这个题意是这个的,有一个robot,要从起点走到

hdu4230 Robot Navigation 迷宫最短路径的条数 BFS 很霸气!!!!!

这个题意是这个的,有一个robot,要从起点走到终点(简化版),它只接受三种命令,

FORWARD X: move forward by X units.
TURN LEFT: turn left (in place) by 90 degrees.
TURN RIGHT: turn right (in place) by 90 degrees.

问:robot从起点走到终点,最短的命令串的长度是多少, 有多少条这样的命令串可以走到终点。

至于FORWARD X: move forward by X units.

也就是说给robot一个向前的命令,它可以走到他前面的任意一个“.”直到遇到“*”或者出了边界。如:

5 6

*....X

.....*

.....*

.....*

N....*

对于图中红色的点, robot从N开始走,只要一个向前的命令就可以走到图中所有的红色点

/*思路 和以前的相比  只要添加一个3维数组记录到每个点的信息即可   即 坐标x y方向dir 三个量
记录下来 到每个点所用的最短时间和路数
*/
#include<stdio.h>/*BFS去求最短的路径的条数  是不能标记用没用过的*/
#include<string.h>
#include<limits.h>
#include<queue>
using namespace std;
#define mod 1000000
int hang,lie,e_x,e_y;
char map[105][105];
struct haha
{
    int x;
    int y;
    int time;
    int dir;     //  不能够用优先队列  要用队列 因为要从某个点向4边扩散记录数组a
  //  friend bool operator <(struct haha a,struct haha b)  
//    {
//        return a.time>b.time;
//    }
    
}now,next,begin;
struct xixi
{
    int num;/*当前最短的次数*/
    int time;
}a[105][105][4];
int step[4][2]={-1,0,0,1,1,0,0,-1};

int can(int x,int y)
{
    if(x>=0&&x<hang&&y>=0&&y<lie&&map[x][y]=='.')
        return 1;
    return 0;
}

void BFS()
{
    int i,k,xx,yy,ans,ti;
    queue<struct haha>que;
    que.push(begin);
    a[begin.x][begin.y][begin.dir].num=1;/*这里的初始化 千万不要忘记*/
    a[begin.x][begin.y][begin.dir].time=0;
    while(!que.empty())
    {
        now=que.front();
        que.pop();
        if(now.x==e_x&&now.y==e_y) continue;
        
        
        for(i=0;i<4;i++)
        {
            xx=now.x+step[i][0];
            yy=now.y+step[i][1];
            if(!can(xx,yy)) continue; /*看忘各个方向试试能不能走 如果不能走 继续下面的也没有意义了 尤其是转身 都不能走了 你转身干嘛啊*/
            if(now.dir==i)/*只有当方向正好与我们要走的方向一样的时候 我们就走*/
            {
                k=1;/*操 k=1 放进了while里面 一个劲死循环*/  
                while(1)
                {
                    xx=now.x+step[i][0]*k;
                    yy=now.y+step[i][1]*k;
                    if(can(xx,yy))
                    {
                        next.dir=i;
                        next.time=now.time+1;
                        next.x=xx;
                        next.y=yy;
                        if(a[xx][yy][i].time>now.time+1)
                        {
                            a[xx][yy][i].time=now.time+1;
                            a[xx][yy][i].num=a[now.x][now.y][now.dir].num;
                            a[xx][yy][i].num=a[xx][yy][i].num%mod;/*可以去掉*/
                            que.push(next);
                            
                        }
                        else if(a[xx][yy][i].time==now.time+1)
                        {
                            a[xx][yy][i].num+=a[now.x][now.y][now.dir].num;
                            a[xx][yy][i].num=a[xx][yy][i].num%mod;/*这里就没有必要push了  否则会死循环*/
                        }
                        
                    }
                    else break;
                    k++;
                }
            }
            else
                if(now.dir==(i+2)%4)/*方向和我们要走的方向相反  这时候只转身 等一样了再走*/
                {
                    next.time=now.time+2;
                    next.dir=i;
                    next.x=now.x;
                    next.y=now.y;
                    if(a[now.x][now.y][i].time>now.time+2)
                    {/*a[now.x][now.y][now.dir].time+2一开始上面写成这样了不是和当前点的其它方向比 而是找和上一状态到当前状态所用时间的较短的一个*/
                        a[now.x][now.y][i].time=now.time+2;
                        a[now.x][now.y][i].num=a[now.x][now.y][now.dir].num;
                        a[now.x][now.y][i].num=a[now.x][now.y][i].num%mod;
                        que.push(next);
                    }
                    else if(a[now.x][now.y][i].time==now.time+2)
                    {
                        a[now.x][now.y][i].num+=a[now.x][now.y][now.dir].num;/*我擦 这里居然让我加了个2 */
                        a[now.x][now.y][i].num=a[now.x][now.y][i].num%mod;
                    }
                    
                }
                else
                {
                    next.time=now.time+1;
                    next.dir=i;
                    next.x=now.x;
                    next.y=now.y;
                    if(a[now.x][now.y][i].time>now.time+1)
                    {
                        a[now.x][now.y][i].time=now.time+1;
                        a[now.x][now.y][i].num=a[now.x][now.y][now.dir].num;
                        a[now.x][now.y][i].num=a[now.x][now.y][i].num%mod;
                        que.push(next);
                    }
                    else if(a[now.x][now.y][i].time==now.time+1)
                    {
                        a[now.x][now.y][i].num+=a[now.x][now.y][now.dir].num;
                        a[now.x][now.y][i].num=a[now.x][now.y][i].num%mod;
                    }
                    
                }

                
                
        }
    }
    ans=INT_MAX;ti=0;
    for(i=0;i<4;i++)
    {
        if(ans>a[e_x][e_y][i].time)
        {
            ans=a[e_x][e_y][i].time;
            ti=a[e_x][e_y][i].num;
        }
        else if(ans==a[e_x][e_y][i].time)
        {
            ti+=a[e_x][e_y][i].num;
            ti=ti%mod;
        }
        
    }
    if(ans==INT_MAX)  printf("0 0\n");
    else
        printf("%d %d\n",ans,ti);
    return ;
}

int main()
{
    int i,j;
    while(scanf("%d %d",&hang,&lie)!=EOF)
    {
        if(hang+lie==0) break;
        for(i=0;i<hang;i++)
            for(j=0;j<lie;j++)
                for(int k=0;k<4;k++)
                {
                    a[i][j][k].time=INT_MAX;
                    a[i][j][k].num=0;
                }
                
                for(i=0;i<hang;i++)
                {
                    scanf("%s",map[i]);
                    for(j=0;j<lie;j++)
                    {
                        if(map[i][j]=='X') {e_x=i;e_y=j;map[i][j]='.';}
                        if(map[i][j]=='N') {begin.dir=0;begin.time=0;begin.x=i;begin.y=j;}
                        else if(map[i][j]=='E') {begin.dir=1;begin.time=0;begin.x=i;begin.y=j;}
                        else if(map[i][j]=='S') {begin.dir=2;begin.time=0;begin.x=i;begin.y=j;}
                        else if(map[i][j]=='W') {begin.dir=3;begin.time=0;begin.x=i;begin.y=j;}
                    }
                    
                }
                BFS();
    }
    return 0;
}
1楼someday7_toi昨天 00:05
我来帮你加人气了.....................

热点排行