UVA 10047-The Monocycle(队列bfs+保存4种状态)

题意:给你一张地图,S代表起点,T代表终点,有一个轮盘,轮盘平均分成5份,每往前走一格恰好转1/5,轮盘只能往前进,但可以向左右转90°,每走一步或是向左向右转90°

要花费1单位的时间,问最少的时间到达终点,如果无法到达,输出  destination not reachable,起点状态是朝北,着地颜色是绿色,到达终点的条件是着地颜色是绿色,方向任意。

解析:bfs搜一遍,但要保存4种状态,分别是坐标x,y,方向和颜色。每次选择有3种,1、向前进,2、左转,3、右转。

代码如下:

#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<set>
#include<map>
#include<queue>
#include<vector>
#include<iterator>
#include<utility>
#include<sstream>
#include<iostream>
#include<cmath>
#include<stack>
using namespace std;
const int INF=1000000007;
const double eps=0.00000001;
const int maxn=26;
int row,col,bex,bey,ans;        //bex,bey是起点坐标
string maze[maxn];              //0:north,1:west,2:south,3:east
bool vis[maxn][maxn][4][5];     //green:0,black:1,red:2,blue:3,white:4
bool in(int x,int y){ return x>=0&&x<row&&y>=0&&y<col; }   //是否在地图内
struct node                            // 保存4种状态以及花费
{
    int x,y,dir,color;
    int dist;
    node(int x=0,int y=0,int dir=0,int color=0,int dist=0)
    :x(x),y(y),dir(dir),color(color),dist(dist){}
};
queue<node> que;
void init()
{   while(!que.empty())  que.pop();
    memset(vis,0,sizeof(vis));
}
void addnode(int x,int y,int dir,int color,int dist)       // 增加节点
{

    if(in(x,y)&&maze[x][y]!=‘#‘&&!vis[x][y][dir][color])  // 在地图内,不是墙,且该种状态未被访问过
    {
        vis[x][y][dir][color]=true;
        que.push(node(x,y,dir,color,dist));
    }
}
void same_dir(int x,int y,int dir,int color,int dist)           // 向前进
{
    if(dir==0)  addnode(x-1,y,dir,(color+1)%5,dist+1);          //颜色要变化
    else if(dir==1)  addnode(x,y-1,dir,(color+1)%5,dist+1);
    else if(dir==2)  addnode(x+1,y,dir,(color+1)%5,dist+1);
    else  addnode(x,y+1,dir,(color+1)%5,dist+1);
}
void dir_change(int x,int y,int dir,int color,int dist)
{
    for(int i=0;i<4;i++)             //改变方向
    {
       if(i==dir||abs(i-dir)==2)  continue;
       addnode(x,y,i,color,dist+1);
    }
}
bool solve()
{
    init();
    que.push(node(bex,bey,0,0,0));      //加入起点
    vis[bex][bey][0][0]=true;
    while(!que.empty())
    {
        node now=que.front();  que.pop();
        if(maze[now.x][now.y]==‘T‘&&now.color==0){ ans=now.dist; return true; } //找到答案
        int x=now.x, y=now.y, dir=now.dir, color=now.color, dist=now.dist;
        same_dir(x,y,dir,color,dist);
        dir_change(x,y,dir,color,dist);
    }
    return false;
}
int main()
{
    int Case=0;
    while(scanf("%d%d",&row,&col)!=EOF)
    {

        if(!row&&!col)  break;
        if(Case++)  printf("\n");
        for(int i=0;i<row;i++)
        {
            cin>>maze[i];
            for(int j=0;j<col;j++)
                if(maze[i][j]==‘S‘) bex=i,bey=j;
        }
        printf("Case #%d\n",Case);
        if(!solve()) printf("destination not reachable\n");
        else  printf("minimum time = %d sec\n",ans);
    }
    return 0;
}
时间: 2024-10-10 09:46:17

UVA 10047-The Monocycle(队列bfs+保存4种状态)的相关文章

UVA 10047 - The Monocycle(BFS)

题目链接:点击打开链接 题意:从起点到终点,每秒可以选择前进.向左.向右转, 每前进一格轮子转到下一个颜色, 一共5中颜色, 开始的时候绿色接触地面,朝北, 要求最后也绿色接触地面,求能否到达目标点以及最短时间. 思路:和普通BFS相比,多了两个附加条件,所以要将状态表示全面,也要对应加两维. 水题. 细节参见代码: #include<cstdio> #include<cstring> #include<algorithm> #include<iostream&g

UVA - 10047 The Monocycle (BFS)

题目大意:有一个n*m的网格,网格上面有的地方有障碍物 现在有一个人,骑着独轮车,要求从一个地方到达另一个地方,骑独轮车时,只能直走,或者左拐,右拐,不能向后走 独轮车的轮子被分成了5部分,每部分都有对应的颜色,刚开始时是绿色向下,当经过一个格子时,颜色就会变换 问从起点出发到终点,到终点时独轮车的绿色颜色向下,需要多久 解题思路:暴力BFS #include <cstdio> #include <cstring> #include <algorithm> #inclu

UVA 10047 - The Monocycle

题目如下:  Problem A: 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 differentcolors as shown in the figure: The colored segments make equal an

uva 10047 - The Monocycle bfs

题目链接 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 (72o) at the center. A

uva 10047 uva live 2035 The Monocycle bfs

// uva 10047 uva live 2035 bfs // 求最短的嘛,肯定先尝试bfs啦 // 确定状态,首先状态里面得有坐标x,y // 还得有朝向,还得有颜色值 // // 这样就是一个状态里面有着三种属性 // 每个状态都只要经历一次,再经历是没有任何意义的 // 用一个que的思维数组记录就行了. // 按照方向爆搜,我先用f[i][j]记录的就是到 // 这一点的最小距离,但是怎么都过不了样例 // 突然明白了,如果只是这样记录最短距离,是不行的 // 因为每次从队列中取出的

UVA 11624 UVA 10047 两道用 BFS进行最短路搜索的题

很少用bfs进行最短路搜索,实际BFS有时候挺方便得,省去了建图以及复杂度也降低了O(N*M): UVA 11624 写的比较挫 #include <iostream> #include <cstdio> #include <cstring> #include <queue> using namespace std; struct node{ int ft; int sta; }flo[1010][1010]; int vis[1010][1010]; st

UVA The Monocycle(BFS 4种状态)

 Problem A: 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

UVA 816 -- Abbott&#39;s Revenge(BFS求最短路)

 UVA 816 -- Abbott's Revenge(BFS求最短路) 有一个 9 * 9 的交叉点的迷宫. 输入起点, 离开起点时的朝向和终点, 求最短路(多解时任意一个输出即可).进入一个交叉点的方向(用NEWS表示不同方向)不同时, 允许出去的方向也不相同. 例如:1 2 WLF NR ER * 表示如果 进去时朝W(左), 可以 左转(L)或直行(F), 如果 朝N只能右转(R) 如果朝E也只能右转.* 表示这个点的描述结束啦! 输入有: 起点的坐标, 朝向, 终点的坐标.然后是各个

UVa 10047 独轮车

题意:独轮车均分为5个部分即五种颜色,每次前进一格恰好换一种颜色接触地面.要求从起点走到终点,但是起点时人是面向北的.绿色接触地面,终点时需要绿色接触地面.朝向哪无所谓.其中,在每个格子,有三种选择,要么前进一格,要么左转90度,要么右转90度.每种选择都是耗时一秒. 思路:将每种约束都看做一个属性,或者说一个状态由4元组决定:横坐标.纵坐标.方向.颜色.这样起始状态知道.终点状态知道,进行bfs搜索即得到最短路径.在状态转化时,有相应的三种选择,前进对应于修改横纵坐标和颜色,左转右转对应于修改