• 独轮车(广搜_队列)


    时限:1000ms 内存限制:10000K 总时限:3000ms

    描述:

    独轮车的轮子上有红、黄、蓝、白、绿(依顺时针序)5种颜色,在一个如下图所示的20*20的迷宫内每走一个格子,轮子上的颜色变化一次。独轮车只能向前推或在原地转向。每走一格或原地转向90度均消耗一个单位时间。现给定一个起点(S)和一个终点(T),求独轮车以轮子上的指定颜色到达终点所需的最短时间。

    输入:

    本题包含一个测例。测例中分别用一个大写字母表示方向和轮子的颜色,其对应关系为:E-东、S-南、W-西、N-北;R-红、Y-黄、B-蓝、W-白、G-绿。在测试数据的第一行有以空格分隔的两个整数和两个大写字母,分别表示起点的坐标S(x,y)、轮子的颜色和开始的方向,第二行有以空格分隔的两个整数和一个大写字母,表示终点的坐标T(x,y)和到达终点时轮子的颜色,从第三行开始的20行每行内包含20个字符,表示迷宫的状态。其中'X'表示建筑物,'.'表示路.

    输出:

    在单独的一行内输出一个整数,即满足题目要求的最短时间。

    输入样例:

    3 4 R N

    15 17 Y

    XXXXXXXXXXXXXXXXXXXX

    X.X...XXXXXX......XX

    X.X.X.....X..XXXX..X

    X.XXXXXXX.XXXXXXXX.X

    X.X.XX....X........X

    X...XXXXX.X.XX.X.XXX

    X.X.XX....X.X..X.X.X

    X.X.X..XX...XXXX.XXX

    X.X.XX.XX.X....X.X.X

    X.X....XX.X.XX.X.X.X

    X.X.X.XXXXX.XX.X.XXX

    X.X.X.XXXXX....X...X

    X.X.......X.XX...X.X

    X.XXX.XXX.X.XXXXXXXX

    X.....XX.......X...X

    XXXXX....X.XXXXXXX.X

    X..XXXXXXX.XXX.XXX.X

    X.XX...........X...X

    X..X.XXXX.XXXX...XXX

    XXXXXXXXXXXXXXXXXXXX 

    输出样例:

    56

    #include<stdio.h>
    struct colornode
    {
        int row;//该状态的行
        int col;//该状态的列
        int color;//该状态的颜色(五种颜色,0-R,1-Y,2-B,3-W,4-G)
        int direction;//该状态的方向(四个方向,0-W,1-S,2-E,3-N,西南东北)
        int num;//该状态的最小步数
    };
    struct colornode s,t;//起点,终点
    struct colornode open[2000];//队列
    int head,tail,openlen=2000;
    int direct[4][2]={{0,-1},{1,0},{0,1},{-1,0}};//向左,下,右,上四个方向转时,行列的增加值
    int a[20][20]={0},n=20;//a数组表示迷宫,n为迷宫边长
    int b[20][20][5][4] = {0};//b数组表示搜索时的所有状态,0为未访问,1为已访问
    
    void readdata();
    void init();
    int search();
    struct colornode moveahead(struct colornode u);//u向前走一格得到的结点v
    struct colornode turntoleft(struct colornode u);//u向左转得到新结点v
    struct colornode turntoright(struct colornode u);//u向右转得到新结点v
    int islegal(struct colornode v);
    int isaim(struct colornode v);
    int used(struct colornode v);//判断该点是否是已经到达过的结点
    void addtoopen(struct colornode v);//将节点v加入队列
    struct colornode takeoutofopen();//从队列头取节点数据
    ///////////////////////////////////////////////////////////////////////////////////////////////////////
    int main()
    {
        readdata();
        init();
        int number=search();
        printf("%d\n",number);
        return 0;
    }
    ///////////////////////////////////////////////////////////////////////////////////////
    int search()
    {
        struct colornode u,v;    
        while(head != tail)
        {
            u = takeoutofopen();//从队列头取数据        
            //////////////////////////////向前走可能到目标
            v = moveahead(u);//向前走        
            if(islegal(v))
            {
                if(isaim(v))
                    return(v.num);
                else if(!used(v))
                    addtoopen(v);
            }
            //////////////////////////////向左,向右转都不会到目标点
            v=turntoleft(u);//左转        
            if(!used(v))
                addtoopen(v);
            /////////////////////////////
            v=turntoright(u);//右转        
            if(!used(v))
                addtoopen(v);
        }
        return 0;//起始点没有通路时
    }
    struct colornode turntoright(struct colornode u)
    {
        struct colornode v;
        v=u;
        v.direction = (u.direction+3)%4;//只要改变方向    
        v.num = u.num+1;
        return(v);
    }
    struct colornode turntoleft(struct colornode u)
    {
        struct colornode v;    
        v=u;
        v.direction = (u.direction+1)%4;//只要改变方向    
        v.num = u.num+1;    
        return(v);
    }
    int used(struct colornode v)
    {
        if(b[v.row][v.col][v.color][v.direction]==0)
            return 0;
        else
            return 1;
    }
    int isaim(struct colornode v)
    {
        if(v.row==t.row &&v.col==t.col &&v.color==t.color)
            return 1;
        else
            return 0;
    }
    int islegal(struct colornode v)
    {
        if(v.row>=0 &&v.row<n &&v.col>=0 &&v.col<n &&a[v.row][v.col]==0)
            return 1;
        else return 0;
    }
    struct colornode moveahead(struct colornode u)
    {
        struct colornode v;    
        v.row=u.row+direct[u.direction][0];    //由方向决定行列增减值
        v.col=u.col+direct[u.direction][1];    
        v.color = (u.color+1)%5;//颜色循环    
        v.direction = u.direction;//直走方向不变    
        v.num = u.num+1;//新的位置步长加1    
        return(v);
    }
    struct colornode takeoutofopen()
    {
        struct colornode v;
        v=open[head++];
        head=head%openlen;
        return v;
    }
    void addtoopen(struct colornode v)
    {
        open[tail++]=v;    
        tail = tail%openlen;
        b[v.row][v.col][v.color][v.direction]=1;//走过的点状态记为1
    }
    //////////////////////////////////////////////////////////////////////
    void readdata()
    {
        char str[50];
        int Berow,Becol;
        char Becolor,Bedir;
        scanf("%d %d %c %c",&Berow,&Becol,&Becolor,&Bedir);//注意%c之前一定要加空格
        s.row = (Berow-1);
        s.col = (Becol-1);
        switch(Becolor)
        {   case 'R':s.color=0;break;//红色块压地,值为0
            case 'Y':s.color=1;break;
            case 'B':s.color=2;break;
            case 'W':s.color=3;break;
            case 'G':s.color=4;break;
        };
        switch(Bedir)
        {    case 'W':s.direction=0;break;//向左,方向值为0
            case 'S':s.direction=1;break;
            case 'E':s.direction=2;break;
            case 'N':s.direction=3;break;
        };
        
        int Enrow,Encol;
        char Encolor;
        scanf("%d %d %c",&Enrow,&Encol,&Encolor);//注意%c之前一定要加空格
        t.row = (Enrow-1);
        t.col = (Encol-1);
        switch(Encolor)
        {    case 'R':t.color=0;break;
            case 'Y':t.color=1;break;
            case 'B':t.color=2;break;
            case 'W':t.color=3;break;
            case 'G':t.color=4;break;
        };
        
        int i=0,j=0;
        for(i=0;i<n;i++)
        {
            scanf("%s",str);//输入一行迷宫字符,再转换成迷宫数字        
            for(j=0;j<n;j++)
            {    if(str[j]=='X')    a[i][j]=1;//1表示墙
            else    a[i][j]=0;//0表示空格
            }    
        }
    }
    void init()
    {
        int i=0,j=0,k=0,l=0;    
        for(i=0;i<n;i++)//
            for(j=0;j<n;j++)//
                for(k=0;k<5;k++)//颜色
                    for(l=0;l<4;l++)//方向
                        b[i][j][k][l]=0;//状态
                    
        head=0;    tail=0;
        s.num=0;//在初始状态走的步数为0
        addtoopen(s);
    }
  • 相关阅读:
    linux会话浅析
    linux memory lock浅析
    浅谈动态库符号的私有化与全局化
    LINUX内核内存屏障
    linux内存屏障浅析
    linux内核mem_cgroup浅析
    记一个linux内核内存提权问题
    linux内核cfs浅析
    linux内核tmpfs/shmem浅析
    linux IPv4报文处理浅析
  • 原文地址:https://www.cnblogs.com/IThaitian/p/2593310.html
Copyright © 2020-2023  润新知