uva 10047 The Monocycle

原题:
A monocycle is a cycle that runs on one wheel and the one we will be considering is a bit more special.
It has a solid wheel colored with five different colors as shown in the figure:
在这里插入图片描述
The colored segments make equal angles (72 o ) at the center. A monocyclist rides this cycle on an
M × N grid of square tiles. The tiles have such size that moving forward from the center of one tile
to that of the next one makes the wheel rotate exactly 72 o around its own center. The effect is shown
in the above figure. When the wheel is at the center of square 1, the midpoint of the periphery of its
blue segment is in touch with the ground. But when the wheel moves forward to the center of the next
square (square 2) the midpoint of its white segment touches the ground.

在这里插入图片描述
Some of the squares of the grid are blocked and hence the cyclist cannot move to them. The cyclist
starts from some square and tries to move to a target square in minimum amount of time. From any
square either he moves forward to the next square or he remains in the same square but turns 90 o left
or right. Each of these actions requires exactly 1 second to execute. He always starts his ride facing
north and with the midpoint of the green segment of his wheel touching the ground. In the target
square, too, the green segment must be touching the ground but he does not care about the direction
he will be facing.
Before he starts his ride, please help him find out whether the destination is reachable and if so the
minimum amount of time he will require to reach it.
Input
The input may contain multiple test cases.
The first line of each test case contains two integers M and N (1 ≤ M, N ≤ 25) giving the
dimensions of the grid. Then follows the description of the grid in M lines of N characters each. The
character ‘#’ will indicate a blocked square, all other squares are free. The starting location of the
cyclist is marked by ‘S’ and the target is marked by ‘T’.
The input terminates with two zeros for M and N.
Output
For each test case in the input first print the test case number on a separate line as shown in the
sample output. If the target location can be reached by the cyclist print the minimum amount of time
(in seconds) required to reach it exactly in the format shown in the sample output, otherwise, print
“destination not reachable”.
Print a blank line between two successive test cases.
Sample Input
1 3
S#T
10 10
#S…#
#…#.##.##
#.##.##.##
.#…##.#
##.##…#.#
#…#.##…
#…##.
…##.##…
#.###…#.
#…###T
0 0
Sample Output
Case #1
destination not reachable
Case #2
minimum time = 49 sec

中文:

有一个独轮车,轮子被均匀的按照弧度分成5种颜色,给你一个迷宫,迷宫中有障碍,起点为S,终点为T,你骑着独轮车在迷宫中可以选择前进和转向,转向90度需要花费1秒,前进一个单位需要花费1秒,初始的时候独轮车轮子绿色部分着地,面朝北方,现在问你能否到终点T,要求到终点时同样也是绿色部分着地,方向不要求,如果能到达终点,求最短到达时间。

代码:

#include <bits/stdc++.h>

using namespace std;
const int maxn=30;

struct node
{
    int x,y;
    int color;
    int face;
    int cnt;
    node(int xx,int yy,int c,int f,int cn)
    {
        x=xx;
        y=yy;
        color=c;
        face=f;
        cnt = cn;
    }
    bool operator < (const node &rhs) const
    {
        return cnt<rhs.cnt;
    }
    bool operator > (const node &rhs) const
    {
        return cnt > rhs.cnt;
    }
};
int n,m;
char maze[maxn][maxn];
bool vis[maxn][maxn][5][4];
bool judge(int x,int y)
{
    if(x>=1&&x<=n&&y>=1&&y<=m&&maze[x][y]!='#')
        return true;
    return false;
}
//绿轮为0,白轮1,蓝2,红3,黑4
//n0,e1,s2,w3
int bfs(int sx,int sy)//初始面朝n,绿色轮
{
    memset(vis,0,sizeof(vis));
    priority_queue<node,vector<node>,greater<node>> Q;
    vis[sx][sy][0][0]=1;
    node tmp(sx,sy,0,0,0);
    Q.push(tmp);
    while(!Q.empty())
    {
        node f=Q.top();
        Q.pop();

        if(maze[f.x][f.y]=='T'&&f.color==0)//找到终点
            return f.cnt;
        //旋转移动
        if(!vis[f.x][f.y][f.color][(f.face+1)%4])
        {
            vis[f.x][f.y][f.color][(f.face+1)%4]=1;
            node t(f.x,f.y,f.color,(f.face+1)%4,f.cnt+1);
            Q.push(t);
        }
        if(!vis[f.x][f.y][f.color][(f.face+3)%4])
        {
            vis[f.x][f.y][f.color][(f.face+3)%4]=1;
            node t(f.x,f.y,f.color,(f.face+3)%4,f.cnt+1);
            Q.push(t);
        }
        if(!vis[f.x][f.y][f.color][(f.face+2)%4])
        {
            vis[f.x][f.y][f.color][(f.face+2)%4]=1;
            node t(f.x,f.y,f.color,(f.face+2)%4,f.cnt+2);
            Q.push(t);
        }
        if(f.face==0)
        {
            if(judge(f.x-1,f.y)&&!vis[f.x-1][f.y][(f.color+1)%5][0])
            {
                vis[f.x-1][f.y][(f.color+1)%5][0]=1;
                node t(f.x-1,f.y,(f.color+1)%5,0,f.cnt+1);
                Q.push(t);
                continue;
            }
        }
        if(f.face==2)
        {
            if(judge(f.x+1,f.y)&&!vis[f.x+1][f.y][(f.color+1)%5][2])
            {
                vis[f.x+1][f.y][(f.color+1)%5][2]=1;
                node t(f.x+1,f.y,(f.color+1)%5,2,f.cnt+1);
                Q.push(t);
                continue;
            }
        }
        if(f.face==1)
        {
            if(judge(f.x,f.y+1)&&!vis[f.x][f.y+1][(f.color+1)%5][1])
            {
                vis[f.x][f.y+1][(f.color+1)%5][1]=1;
                node t(f.x,f.y+1,(f.color+1)%5,1,f.cnt+1);
                Q.push(t);
                continue;
            }
        }
        if(f.face==3)
        {
            if(judge(f.x,f.y-1)&&!vis[f.x][f.y-1][(f.color+1)%5][3])
            {
                vis[f.x][f.y-1][(f.color+1)%5][3]=1;
                node t(f.x,f.y-1,(f.color+1)%5,3,f.cnt+1);
                Q.push(t);
                continue;
            }
        }


    }

    return -1;
}

int main()
{
    ios::sync_with_stdio(false);
    int t=1;
    while(cin>>n>>m,n+m)
    {
        int sx,sy;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                cin>>maze[i][j];
                if(maze[i][j]=='S')
                {
                    sx=i;
                    sy=j;
                }
            }
        }


        int ans=bfs(sx,sy);
        if(t>1)
            cout<<endl;
        cout<<"Case #"<<t++<<endl;
        if(ans==-1)
        {
            cout<<"destination not reachable"<<endl;
        }
        else
        {
            cout<<"minimum time = "<<ans<<" sec"<<endl;
        }
    }
    return 0;
}







解答:

明显的广搜,由于在每个格子当中会有不同的朝向以及不同颜色部分的轮子着地,所以需要用状态表现出来,用来判定当前状态是否出现过。
设置vis[x][y][color][face]表示在格子(x,y)处,颜色为color部分的轮子着地,朝向为face的状态是否遍历过。

由于计算最短到达时间,使用广搜,但是这里注意,由于最后到达终点的状态可以有多种朝向,所以需要用优先队列来获取步数最少的状态来进行扩展。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值