1. 程式人生 > >【NOJ1044】獨輪車【廣搜】

【NOJ1044】獨輪車【廣搜】

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

廣搜進階版。每個狀態對應四個引數:x,y,顏色,方向。所以用四維陣列記錄狀態。

對於某一狀態來說,其下一個狀態有三種情況:前進、左轉和右轉。

#include <iostream>
#include <cstdio>
#include <queue>
#include <cmath>

using namespace std;

int dx[4]={-1,0,1,0};
int dy[4]={0,1,0,-1};
int gx,gy,gc;
char mapp[20][20];
bool used[20][20][4][5];
struct node
{
    int x,y;
    int dir;
    int color;
    int step;
};
node now,next;

bool judge()
{
    int x,y;
    x=now.x+dx[now.dir];
    y=now.y+dy[now.dir];
    if(x>=0&&x<20&&y>=0&&y<20&&used[x][y][now.x][(now.color+1)%5]==false&&mapp[x][y]=='.') return true;
    else return false;
}
int bfs()
{
    now.step=0;
    queue<node>q;
    q.push(now);


    while(!q.empty())
    {
        now=q.front();
        q.pop();
        if(now.x==gx-1&&now.y==gy-1&&now.color==gc)
        {
            return now.step;
        }
        if(judge())//前進
        {
            next.x=now.x+dx[now.dir];
            next.y=now.y+dy[now.dir];
            next.dir=now.dir;
            next.color=(now.color+1)%5;
            next.step=now.step+1;
            q.push(next);
        }

        next.x=now.x;
        next.y=now.y;
        next.color=now.color;
        next.dir=(now.dir+1)%4;//右轉
        if(used[next.x][next.y][next.dir][next.color]==false)
        {
            next.step=now.step+1;
            q.push(next);
            used[next.x][next.y][next.dir][next.color]=true;
        }
        next.dir=(now.dir+3)%4;//左轉
        if(used[next.x][next.y][next.dir][next.color]==false)
        {
            next.step=now.step+1;
            q.push(next);
            used[next.x][next.y][next.dir][next.color]=true;
        }
    }
    return 0;
}

int main()
{
    char dire,cc;
    cin>>now.x>>now.y;
    now.x--;now.y--;
    getchar();
    cin>>cc;
    getchar();
    cin>>dire;
    switch(dire)
    {
        case 'E':now.dir=1;break;
        case 'S':now.dir=2;break;
        case 'W':now.dir=3;break;
        case 'N':now.dir=0;break;
    }
    switch(cc)
    {
        case 'R': now.color=0;break;
        case 'Y': now.color=1;break;
        case 'B': now.color=2;break;
        case 'W': now.color=3;break;
        case 'G': now.color=4;break;
    }
    cin>>gx>>gy;
    getchar();
    cin>>cc;
    switch(cc)
    {
        case 'R' :gc=0;break;
        case 'Y' :gc=1;break;
        case 'B' :gc=2;break;
        case 'W' :gc=3;break;
        case 'G' :gc=4;break;
    }
    for(int i=0;i<20;i++)
    {
        scanf("%s",mapp[i]);
    }

    printf("%d\n",bfs());
    return 0;
}