2012-12-01 19:07:54Morris

[ZJ][BFS] d373. 5. 乳酪的誘惑

內容 :

這個問題跟傳統的老鼠走迷宮問題不太一樣,給定一個四方形的格點空間
x 座標與y 座標由左下角原點以0 開始往右和往上遞增,裡面有一個區域是鼠窩,另外有一個區域是乳酪屋
此外還有很多障礙物是用來阻擋鼠輩的橫行,也就是障礙物是不可穿越的。
在此空間裡可能沒有路可以從鼠窩走到乳酪屋,此種情況你必須回報沒有路徑
如果有路可以連接鼠窩跟乳酪屋的話,你必須算出從鼠窩走到乳酪屋的最短路徑。
老鼠的每一步只能往四個方向走:上、下、左、右,不能走對角方向。出發點與終點可以是鼠窩與乳酪屋的任何一個位置。
以圖一為例,鼠窩到乳酪屋的最短距離為15,由鼠窩裡圓圈所標示的點(10,2)往左出發走到乳酪屋中圓圈所標示的點(1,8)。
鼠窩與乳酪屋的形狀一定是一條直線,障礙物可以是一點可以是一條直線也可以是一個矩形區域
圖一中的障礙物是由三個點與兩條直線所構成,分別為點(2,6)、(3,5)、與(4,4)和線(4,3)~(7,3)與(7,4)~(7,9)。
在找尋最短路徑時,不要只派遣一隻老鼠出任務,這樣會累死這隻可憐的倒霉鼠的。

 

輸入說明 :

輸入的第一行為兩個整數,描述方形格點空間的大小,第一個表示行的數目,第二個表示列的數目
在此問題中行和列的數目都不會超過1000 (<=1000)。
接下來“.mb”表示後面用兩點來描述鼠窩的位置,每個點先x 座標再y 座標,兩個點沒有固定的先後排序。
接下來“.cb”表示後面用兩點來描述乳酪屋的位置,兩個點也沒有固定的先後排序。
最後“.bb”表示後面開始每一行描述一個障礙物的位置,不管是一點還是一條線都是用兩點來表示
最後以“.be”表示結束。

輸出說明 :

沒有路徑的話,輸出“no path”。有路徑的話輸出最短路徑距離。

範例輸入 :

以圖一為例,其輸入檔案如下:
14 10
.mb 10 4 10 1
.cb 1 8 4 8
.bb
2 6 2 6
3 5 3 5
4 4 4 4
4 3 7 3
7 9 7 4
.be

範例輸出 :

15

提示 :

出處 :

97全國能力縣賽 (管理:pcshic)

以前寫了好久都沒過,這次回頭寫一次 BFS 通過

#include <stdio.h>
#include <queue>
using namespace std;
char g[1000][1000] = {};
int dis[1000][1000] = {};
int n, m, ax, ay, bx, by, tmp;
int i, j, k;
void color(int c, int ax, int ay, int bx, int by) {
    if(ax > bx) tmp = ax, ax = bx, bx = tmp;
    if(ay > by) tmp = ay, ay = by, by = tmp;
    int i, j;
    for(i = ax; i <= bx; i++)
        for(j = ay; j <= by; j++)
            g[i][j] = c;
}
struct Pt {
    int x, y;
};
void solve() {
    queue<Pt> Q;
    Pt p, tn;
    int tx, ty;
    int dir[4][2] = {{1,0},{0,1},{-1,0},{0,-1}};
    for(i = 0; i < n; i++)
        for(j = 0; j < m; j++)
            if(g[i][j] == 1) {
                p.x = i, p.y = j;
                Q.push(p);
                dis[i][j] = 1;
            }
    int ans = 0xfffff;
    while(!Q.empty()) {
        tn = Q.front();
        Q.pop();
        for(i = 0; i < 4; i++) {
            tx = tn.x + dir[i][0], ty = tn.y + dir[i][1];
            if(tx < 0 || ty < 0 || tx >= n || ty >= m)
                continue;
            if(dis[tx][ty] == 0 && g[tx][ty] != 3) {
                dis[tx][ty] = dis[tn.x][tn.y]+1;
                if(g[tx][ty] == 2 && dis[tx][ty] < ans)
                    ans = dis[tx][ty];
                p.x = tx, p.y = ty;
                Q.push(p);
            }
        }
    }
    if(ans == 0xfffff)
        puts("no path");
    else
        printf("%d\n", ans-1);
}
int main() {
    scanf("%d %d", &n, &m);
    scanf("%*s %d %d %d %d", &ax, &ay, &bx, &by);
    color(1, ax, ay, bx, by);
    scanf("%*s %d %d %d %d", &ax, &ay, &bx, &by);
    color(2, ax, ay, bx, by);
    char cmd[20];
    gets(cmd);
    gets(cmd);
    while(gets(cmd)) {
        if(cmd[0] == '.')   break;
        sscanf(cmd, "%d %d %d %d", &ax, &ay, &bx, &by);
        color(3, ax, ay, bx, by);
    }
    solve();
    return 0;
}