独轮车

描述:

独轮车的轮子上有红、黄、蓝、白、绿(依顺时针序)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;
int sx, sy, sd, sc;
int fx, fy, fc;
char maze[21][21];
int visited[21][21][5][4];
int dir[4][2]= {{-1,0}, {0,1}, {1,0}, {0,-1}};
typedef struct Node
{
    int x;
    int y;
    int color;
    int direction;
    int time;
    Node(int x=0, int y=0, int color=0, int direction=0, int time=0)
    :x(x), y(y), color(color), direction(direction), time(time){};
}status;

int direct(char ch)
{
    switch(ch)
    {
        case 'N':
            return 0;
        case 'E':
            return 1;
        case 'S':
            return 2;
        case 'W':
            return 3;
    }
}

int color(char ch)
{
    switch(ch)
    {
        case 'R':
            return 0;
        case 'Y':
            return 1;
        case 'B':
            return 2;
        case 'W':
            return 3;
        case 'G':
            return 4;
    }
}

//直走
status toStraight(status u)
{
    status v = u;
    v.x = v.x+dir[u.direction][0];
    v.y = v.y+dir[u.direction][1];
    v.color = (v.color+1)%5;
    v.time ++;
    return v;
}

//右转
status toRight(status u)
{
    status v = u;
    v.direction = (v.direction+1)%4;
    v.time ++;
    return v;
}

//左转
status toLelf(status u)
{
    status v = u;
    v.direction = (v.direction+3)%4;
    v.time ++;
    return v;
}

bool isAim(status u)
{
    if(u.x == fx && u.y == fy && u.color == fc)
        return true;
    else
        return false;
}

bool isLegal(status u)
{
    if(u.x > 0 && u.x < 21 && u.y > 0 && u.y < 21 && (!visited[u.x][u.y][u.color][u.direction]) && maze[u.x][u.y] == '.')
        return true;
    else
        return false;
}
int bfs()
{
    queue<Node> q;
    status s = Node(sx, sy, sc, sd, 0);
    q.push(s);
    visited[sx][sy][sc][sd] = 1;
    while(!q.empty())
    {
        s = q.front();
        q.pop();
        status v = toStraight(s);
        if(isLegal(v))
        {
            if(isAim(v))
                return v.time;
            visited[v.x][v.y][v.color][v.direction] = 1;
            q.push(v);
        }

        v = toLelf(s);
        if(!visited[v.x][v.y][v.color][v.direction])
        {
            visited[v.x][v.y][v.color][v.direction] = 1;
            q.push(v);
        }

        v = toRight(s);
        if(!visited[v.x][v.y][v.color][v.direction])
        {
            visited[v.x][v.y][v.color][v.direction] = 1;
            q.push(v);
        }
    }
    return -1;
}
int main()
{
    char c, d;
    cin >> sx >> sy >> c >> d;
    sc = color(c), sd = direct(d);
    cin >> fx >> fy >> c;
    fc = color(c);
    for(int i = 1; i <= 20; i++)
    {
        for(int j = 1; j <= 20; j++)
        {
            cin >> maze[i][j];
        }
    }
    cout << bfs() << endl;
    return 0;
}



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值