網教17. 有喫的!

婦添小有一個很厲害的技能:發現喫的!如果有好喫的東西,不論多遠,只要一聞就能知道在哪裏。這天他剛剛在程設rejudge完,忽然鼻子一抽——有喫的!他決定馬上趕去喫這麼好喫的東西。

語文男爲了考驗婦添小的品味,在路中間放了很多饅頭,看他會不會餓的先喫饅頭。婦添小當然不會讓這種雕蟲小計得逞!爲了保持自己的品味,他決定繞開所有的饅頭。Eureka受到婦添小邀請,運用絕世法力構造了很多傳送點,任意兩個傳送點之間都能瞬移(當然傳不傳,傳到哪裏都可以隨心所欲)。婦添小每次移動只能走上下左右四個方向(瞬移除外,並且瞬移不耗費時間)。現在,婦添小最短多長時間能喫到好喫的東西呢?

(當然,爲了出題我們隱瞞了一些事實:不僅好喫的不見了,路上的饅頭竟然也不翼而飛了,這真真是個悲傷的故事T.T)

輸入:

第一行包含兩個數字n,m(1<=n,m<=2000)

接下來包含n行,每行m個字符,表示現在的地圖。'.'表示空地,'M‘表示饅頭,‘E’表示傳送點,'N'表示婦添小所在的位置,'C'表示喫的。'N'和‘C'在地圖中出現且僅出現一次。

輸出:

一個數字,表示婦添小最快能多長時間喫到好喫的。如果永遠喫不到,只能說明傳送點不夠多,輸出“Bad Eureka”。

提示:如果時間顯示是0.004等很短的時間,但是最後評測爲TLE,這時候實際上是因爲開的數組過大,超出了內存限制。

  測試輸入關於“測試輸入”的幫助 期待的輸出關於“期待的輸出”的幫助 時間限制關於“時間限制”的幫助 內存限制關於“內存限制”的幫助 額外進程關於“{$a} 個額外進程”的幫助
測試用例 1 以文本方式顯示
  1. 6 6↵
  2. ...E..↵
  3. EMM.M.↵
  4. .M..M.↵
  5. .MC.M.↵
  6. .MMM..↵
  7. N..E..↵
以文本方式顯示
  1. 7↵
1秒 64M 0
題解:
看着就是一個簡單的搜索題目(實際也不太難),我一開始想的辦法是求所有E到C的距離找出最小值記爲a,找N到最近的E的距離記爲b,N不走E直接到C的距離爲c,最後看a+b和c哪個大。但是一開始用DFS交了幾發,出了3個RE,不知道是什麼鬼。然後後來用BFS,有一個超時。後來發現是找所有E到C的距離導致時間複雜度太高,直接找C到最近的E的距離記爲a即可。然後就過了。
可是我還是不知道爲什麼不能用DFS。
代碼:
#include<stdio.h>  
#include<string.h>  
char map1[2005][2005];  
int dx[] = { 1, -1, 0, 0 };  
int dy[] = { 0, 0, 1, -1 };  
int n, m;  
int vis[2005][2005] = { 0 };  
struct node  
{  
    short x, y;  
    int index;  
}q[4000005];  
int bfs(int x1, int y1)  
{  
    memset(vis, 0, sizeof(vis));  
//  memset(q, 0, sizeof(q));  
    int front = 0, rear = 1, a, b;  
    q[front].x = x1;  
    q[front].y = y1;  
    q[front].index = 0;  
    vis[x1][y1] = 1;  
    while (front<rear){  
        if (map1[q[front].x][q[front].y] == 'C')  
            return q[front].index;  
        for (int i = 0; i<4; i++){  
            a = q[front].x + dx[i];  
            b = q[front].y + dy[i];  
            if (a<0 || b<0 || a>n - 1 || b>m - 1 || vis[a][b] || map1[a][b] == 'M')  
                continue;  
            else{  
                vis[a][b] = 1;  
                q[rear].x = a;  
                q[rear].y = b;  
                q[rear].index = q[front].index + 1;  
                rear++;  
            }  
        }  
        front++;  
    }  
    return 0x3f3f3f3f;  
}  
int bfs2(int x1, int y1)  
{  
    memset(vis, 0, sizeof(vis));  
//  memset(q, 0, sizeof(q));  
    int front = 0, rear = 1, a, b;  
    q[front].x = x1;  
    q[front].y = y1;  
    q[front].index = 0;  
    vis[x1][y1] = 1;  
    while (front<rear){  
        if (map1[q[front].x][q[front].y] == 'E')  
                return q[front].index;  
        for (int i = 0; i<4; i++){  
            a = q[front].x + dx[i];  
            b = q[front].y + dy[i];  
            if (a<0 || b<0 || a>n-1 || b>m-1 || vis[a][b]||map1[a][b]=='M')  
                continue;  
            else{  
                vis[a][b] = 1;  
                q[rear].x = a;  
                q[rear].y = b;  
                q[rear].index = q[front].index + 1;  
                rear++;  
            }  
        }  
        front++;  
    }  
    return 0x3f3f3f3f;  
}  
int main()  
{  
    scanf("%d%d", &n, &m);  
    getchar();  
    int i, j;  
    int sx, sy,ex,ey;  
    for (i = 0; i < n; i++)  
    {  
        for (j = 0; j < m; j++)  
        {  
            scanf("%c", &map1[i][j]);  
            if (map1[i][j] == 'N')  
            {  
                sx = i;  
                sy = j;  
            }  
            if (map1[i][j] == 'C')  
            {  
                ex = i;  
                ey = j;  
            }  
        }  
        getchar();  
    }  
    int min1, min2, min3;  
    min1 = bfs2(ex, ey);  
    min2 = bfs2(sx, sy);  
    min3 = bfs(sx, sy);  
  
    int ans;  
    if ((min1 == 0x3f3f3f3f || min2 == 0x3f3f3f3f) && min3 == 0x3f3f3f3f)  
        printf("Bad Eureka\n");  
    else  
    {  
        ans = (min1 + min2) < min3 ? (min1 + min2) : min3;  
        printf("%d\n", ans);  
    }  
}  


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章