独轮车 题目代码如下 细心和耐心就好

/*1044.独轮车
时限: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<iostream>
#include<queue>
using namespace std;
queue<int>x ;//横坐标队列
queue<int>y ;//纵坐标队列
queue<int>color ;//颜色队列
queue<int>dire ;//方向队列

int x1 , y1 , x2 , y2 ;//起点和终点的坐标
int color1 , dire1 ;//起始方向和颜色
int color2 ;//终点的颜色
 
char a , b, c ;//起点的颜色、方向和重点的颜色
char map[21][21] = {0} ; //地图
int  map1[21][21][5][4] = {0} ;//每一个位置具有四个状态 横坐标、纵坐标、方向、颜色 计算时间


//!!!!!!一个找了两天的bug 左下右上的数组和dire1的数据对应 dire1必须是西南东北

int dr[4] = {0 ,1 ,0 ,-1 } ;//左下右上
int dc[4] = {-1 ,0 ,1 ,0} ;
int x0 , y0 , row , col , color0 , dire0 ;
//x0 ,y0 ,color0,dire0是四个队列的队首元素 row1,col1是走一格后的位置

void input() ;//输入数据
void init() ;//对数据初始化把字母变为数字好处理
int bfs() ; //广搜找答案
void move() ;//变换到新状态


int main()
{
 input() ;//输入数据
 bfs() ;//找答案
}
void input()
{
 int i, j ;
 cin >> x1 >> y1 >> a >> b >> x2 >> y2 >> c ;//输入数据
 for(i = 1 ; i <= 20 ; i++)
 {
  for(j = 1 ; j <= 20 ; j++)
  {
   cin >> map[i][j] ;
  }
 }
    init() ; //初始化
}
int bfs()
{
 int i ;

 while(!x.empty())
 {
 
     x0 = x.front() ;//访问横、纵坐标、方向、颜色队首元素并使其出队
     x.pop() ; 
     y0 = y.front() ;
     y.pop() ;
     dire0 = dire.front() ;
     dire.pop() ;
     color0 = color.front() ;
     color.pop() ;
   
        move() ; //变换到新状态 
    
     for(i = 0 ; i <= 3 ; i++)//达到目标状态就输出 因为题中方向位置所以要for循环一下
     {
      if(map1[x2][y2][color2][i] != 0)//走到了目标状态
      {
       cout << map1[x2][y2][color2][i] << endl ;
       return 0 ;
      }
     }       
 }
     return -1 ; //未找到答案返回 -1 
}
void init() //R-红、Y-黄、B-蓝、W-白、G-绿
{

 if(a == 'R')
 {
  color1 = 0 ;
 }
 if(a == 'Y')
 {
  color1 = 1 ;
 }
 if(a == 'B')
 {
  color1 = 2 ;
 }
 if(a == 'W')
 {
  color1 = 3 ;
    }
 if(a == 'G')
 {
  color1 = 4 ;
 }
 
 
 if(b == 'W')
 {
  dire1 = 0 ;
 }
 if(b == 'S')
 {
  dire1 = 1 ;
 } 
   if(b == 'E')
 {
  dire1 = 2 ;
 }
 if(b == 'N')
 {
  dire1 = 3 ;
 }
  
 
 if(c == 'R')
 {
  color2 = 0 ;
 }
 if(c == 'Y')
 {
  color2 = 1 ;
 }
 if(c == 'B')
 {
  color2 = 2 ;
 }
 if(c == 'W')
 {
  color2 = 3 ;
    }
 if(c == 'G')
 {
  color2 = 4 ;
 }
     
   
 x.push(x1) ;//起点的横、纵坐标、颜色、方向入队
 y.push(y1) ;
 color.push(color1) ;
 dire.push(dire1) ; 
 
 map1[x1][y1][color1][dire1] = 0 ;//起始位置的累计时间为0
}
void move()
{
     //变换颜色和方向 坐标直接加减 颜色和方向取模循环 
     //元素入队
  //步数+1
   
 row = x0 + dr[dire0] ;
 col = y0 + dc[dire0] ;
 if(map[row][col] == '.' && map1[row][col][(color0+1)%5][dire0] == 0)//走一步费一个单位时间
    {
      map1[row][col][(color0+1)%5][dire0] = map1[x0][y0][color0][dire0] + 1 ;
      x.push(row);
      y.push(col);
      color.push((color0+1)%5);
      dire.push(dire0);
    }
 if(map1[x0][y0][color0][(dire0+1)%4] == 0)//直接转换方向 
    {
      map1[x0][y0][color0][(dire0+1)%4] = map1[x0][y0][color0][dire0] + 1 ;
      x.push(x0);
      y.push(y0);
      color.push(color0);
      dire.push((dire0+1)%4);
 }
    if(map1[x0][y0][color0][(dire0-1+4)%4] == 0)//直接转换方向 
    {
      map1[x0][y0][color0][(dire0-1+4)%4] = map1[x0][y0][color0][dire0] + 1 ;
      x.push(x0);
      y.push(y0);
      color.push(color0);
      dire.push((dire0-1+4)%4);
 }
}

猜你喜欢

转载自blog.csdn.net/irving0323/article/details/78606966