zoj3865

zoj3865

這裏寫圖片描述

zoj3865

解題思路:
首先這道題求的是起點到終點之間的最短到達時間。我們可以維護一個三維的狀態(x,y,direct),其中direct是光標指向的方向,可以理解爲機器人robot是有方向的。光標所在的方向即爲當前位置robot所面對的方向。如此一來,每一秒鐘對於robot可以有四種操作:

  1. 朝着當前面對的方向前進一格,對應於題中按下一個按鈕,機器人向對應方向移動
  2. 轉變一次面朝的方向。對應於題中光標左移一格或者光標右移一格。
  3. 原地不動。

    需要值得注意的是,每過p秒所有按鈕會向右移動一格,也就是說若當前節點的時間模p爲0,則應該(direct+3)%4,(direct = 0,1,2,3分別對應於左,右,上,下)。而此操作必須在此節點入隊前處理,否則vis數組含義錯誤。
    由於寬搜的性質,若取出隊頭節點爲終點節點,即可保證其時間花費是最少。也正好說明了vis數組的必要性。
    另外,對於第三種操作,即原地不動,如果原地不動後,沒有發生因時間模p爲0而導致的按鈕右移而使狀態發生改變,那麼就不應該入隊此新節點。此處要注意邏輯關係。
    下面帖代碼:

#include <cstdio>
#include <cstring>
#include <queue>
#define maxsize 12
using namespace std;
int ns, m, p;
char afx[maxsize][maxsize];
bool vis[maxsize][maxsize][4];
int sx, sy, ex, ey;

const int xx[] = {0, 0, -1, 1};
const int yy[] = { -1, 1, 0, 0};
struct node
{
    int x;
    int y;
    int ti;
    int direc;
    node()
    {}
    node(int a, int b, int c, int d)
    {
        x = a;
        y = b;
        ti = c;
        direc = d;
    }
};
int bfs()
{
    std::queue <node> q;
    vis[sx][sy][0] = true;
    node start = node(sx, sy, 0, 0);
    q.push(start);
    while(!q.empty())
    {
        node n = q.front();
        q.pop();
        if(n.x == ex && n.y == ey)
            return n.ti;

        int nx = n.x + xx[n.direc];
        int ny = n.y + yy[n.direc];
        node next = node(nx, ny, n.ti + 1, n.direc);
        if(next.ti % p == 0)
            next.direc = (next.direc + 3) % 4;
        if(nx < ns && nx >= 0 && ny < m && ny >= 0 && afx[nx][ny] != '*' && !vis[nx][ny][next.direc])
        {
            q.push(next);
            vis[nx][ny][next.direc] = true;
        }


        node next4 = node(n.x, n.y, n.ti + 1, (n.direc + 3) % 4);
        if(next4.ti % p == 0)
            next4.direc = (next4.direc + 3) % 4;
        if(!vis[next4.x][next4.y][next4.direc])
        {
            q.push(next4);
            vis[next4.x][next4.y][next4.direc] = true;
        }


        node next2 = node(n.x, n.y, n.ti + 1, (n.direc + 1) % 4);
        if(next2.ti % p == 0)
            next2.direc = (next2.direc + 3) % 4;
        if(!vis[next2.x][next2.y][next2.direc])
        {
            q.push(next2);
            vis[next2.x][next2.y][next2.direc] = true;
        }


        node next3 = node(n.x, n.y, n.ti + 1, n.direc);
        if(next3.ti % p == 0)
        {
            next3.direc = (next3.direc + 3) % 4;

        }
        if(!vis[next3.x][next3.y][next3.direc])
        {         
            q.push(next3);
            vis[next3.x][next3.y][next3.direc] = true;
        }
    }
    return -1;
}
void initial()
{
    for(int i = 0; i < ns; i++)
        for(int j = 0; j < m; j++)
        {
            if(afx[i][j] == '@')
            {
                sx = i;
                sy = j;
            }
            else if(afx[i][j] == '$')
            {
                ex = i;
                ey = j;
            }
        }
    memset(vis, false, sizeof(vis));
}
int main()
{
    int t;
    scanf("%d", &t);
    while(t--)
    {
        scanf("%d%d%d", &ns, &m, &p);
        for(int i = 0; i < ns; i++)
            scanf("%s", afx[i]);
        initial();
        int ans = bfs();
        if(ans != -1)
            printf("%d\n", ans);
        else
            printf("YouBadbad\n");
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章