The Monocycle UVA 10047

说说:

这算是一道比较难的题目了,拖到今天终于搞定啦!题意是这样的,有如下这样一个棋盘:一个轮子从S出发开始运动,它有三个选择,沿原方向向前滚一格,或者在原地向左或向右转90度,并且无论是滚动还是转身都将耗时一秒。其中轮子由五种颜色组成,每滚动一个,与地面接触的颜色都将变换一次,如下图所示。假设开始的时候轮子停在S初,方向朝北,颜色为绿色,则能否到达目的地T,且颜色仍旧为绿色,求最短时间。

分析:开始的时候想法非常简单,就是DFS嘛,看能不能到达T,到时候再看看颜色的状态都差不多了。其实这是不对的,因为它很有可能在第一次到达T的时候,颜色状态是不对的,然后说不定去绕了一圈之后就对了。因为并没有规定,不能重复经过一个节点。这样的话就比较麻烦了。最后经过刘汝佳的《算法竞赛训练指南》里的提示,才发行应该将轮子所处的位置,颜色,方向合起来定义为一个状态才是合理的。因为这样才是唯一的。因此,有了这个想法之后,然后简单的用一下BFS问题就解决了。

源代码:

#include <stdio.h>
#include <string.h>
#define MAX 25+5

typedef struct {
  int x;
  int y;
  int color;
  int dir;
  int time;
}NODE;

NODE queue[20000];
int M,N,sx,sy,ans,front,rear;
char maze[MAX][MAX];
char vis[MAX][MAX][5][4];//标记状态是否被访问

int bfs(int,int,int,int,int);
int inqueue(int,int,int,int,int);//将状态加入队列
int main(){
  int i,j,T=1;
  //freopen("data","r",stdin);
  while(scanf("%d%d",&M,&N)){
   if(M==0&&N==0)
     break;
   else if(T>1)
     putchar('\n');

   for(i=0;i<M;i++)
     scanf("%s",maze[i]);

   for(i=0;i<M;i++)
     for(j=0;j<N;j++)
       if(maze[i][j]=='S')
         sx=i,sy=j;
   memset(vis,0,sizeof(vis));
   front=rear=0;
   printf("Case #%d\n",T++);

   if(bfs(sx,sy,0,0,0))
     printf("minimum time = %d sec\n",ans);
   else
     printf("destination not reachable\n");

  }

  return 0;
}

int bfs(int x,int y,int dir,int color,int time){
  int val;

  inqueue(x,y,dir,color,time);

  while(front<rear){
    if(inqueue(queue[front].x,queue[front].y,(queue[front].dir+1)%4,queue[front].color,queue[front].time+1))
      return 1;//往一个方向转动

    if(inqueue(queue[front].x,queue[front].y,(queue[front].dir+3)%4,queue[front].color,queue[front].time+1))
      return 1;//往另一个方向转动

    switch(queue[front].dir){//根据当前的方向移动一格
     case 0: val=inqueue(queue[front].x-1,queue[front].y,queue[front].dir,(queue[front].color+1)%5,queue[front].time+1);
             break;
     case 1: val=inqueue(queue[front].x,queue[front].y+1,queue[front].dir,(queue[front].color+1)%5,queue[front].time+1);
             break;
     case 2: val=inqueue(queue[front].x+1,queue[front].y,queue[front].dir,(queue[front].color+1)%5,queue[front].time+1);
             break;
     case 3: val=inqueue(queue[front].x,queue[front].y-1,queue[front].dir,(queue[front].color+1)%5,queue[front].time+1);
             break;
      }

    if(val)
      return 1;

    front++;
  }

  return 0;
}

int inqueue(int x,int y,int dir,int color,int time){//将状态加入队列
  if(x<0||x>=M||y<0||y>=N||vis[x][y][color][dir]||maze[x][y]=='#')
    return 0;
  else if(maze[x][y]=='T'&&color==0){
    ans=time;
    return 1;
  }
  vis[x][y][color][dir]=1;
  queue[rear].x=x;
  queue[rear].y=y;
  queue[rear].dir=dir;
  queue[rear].color=color;
  queue[rear].time=time;
  rear++;

  return 0;
}
时间: 2024-08-26 12:05:51

The Monocycle UVA 10047的相关文章

The Monocycle,UVa 10047(状态记录广搜)

题目链接:http://acm.hust.edu.cn/vjudge/problem/36951 题意: 一辆独轮车,他的车轮每72度变一个颜色(蓝,白,绿,黑,红)..每秒有3种操作,左转,右转,或者前进,前进的时候车轮的颜色会向前进一色.要求出到终点且车轮触底颜色为蓝色的最小时间. 初始时间为轮子触底为蓝,朝向北 源代码: #include<iostream> #include<cstdio> #include<cstring> #include<queue&

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 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 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 - 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 独轮车

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

图论算法与模型(训练指南题库)

一.基础题目 1.UVA 11624 Fire!迷宫问题 多源BFS 题意: 帮助joe走出一个大火蔓延的迷宫,其中joe每分钟可往上下左右四个方向之一走,所有着火的格子都会蔓延(空格与着火格有公共边,下一分钟这个空格也会着火).迷宫中有一些障碍格,joe和火都无法进入,当joe走到一个边界的格子我们认为他走出了迷宫 输出R行C列的迷宫,#表示墙,.表示空地,J表示joe,F是着火格 如果能走出,输出最少时间否则,impossible 思路: 先预处理出每个点的起火时间,可以用多源点BFS直接处