24h購物| | PChome| 登入
2013-10-02 14:13:21| 人氣1,525| 回應0 | 上一篇 | 下一篇

[UVA][TSP] 10937 - Blackbeard the Pirate

推薦 0 收藏 0 轉貼0 訂閱站台

Problem D: Blackbeard the Pirate

Blackbeard the Pirate has stashed up to 10 treasures on a tropical island, and now he wishes to retrieve them. He is being chased by several authorities however, and so would like to retrieve his treasure as quickly as possible. Blackbeard is no fool; when he hid the treasures, he carefully drew a map of the island which contains the position of each treasure and positions of all obstacles and hostile natives that are present on the island.

Given a map of an island and the point where he comes ashore, help Blackbeard determine the least amount of time necessary for him to collect his treasure.

Input consists of a number of test cases. The first line of each test case contains two integers h and w giving the height and width of the map, respectively, in miles. For simplicity, each map is divided into grid points that are a mile square. The next h lines contain w characters, each describing one square on the map. Each point on the map is one of the following:

  •  @  The landing point where Blackbeard comes ashore.
  •  ~  Water. Blackbeard cannot travel over water while on the island.
  •  #  A large group of palm trees; these are too dense for Blackbeard to travel through.
  •  .  Sand, which he can easily travel over.
  •  *  A camp of angry natives. Blackbeard must stay at least one square away or risk being captured by them which will terminate his quest. Note, this is one square in any of eight directions, including diagonals.
  •  !  A treasure. Blackbeard is a stubborn pirate and will not leave unless he collects all of them.
Blackbeard can only travel in the four cardinal directions; that is, he cannot travel diagonally. Blackbeard travels at a nice slow pace of one mile (or square) per hour, but he sure can dig fast, because digging up a treasure incurs no time penalty whatsoever.

The maximum dimension of the map is 50 by 50. The input ends with a case where both h and w are 0. This case should not be processed.

For each test case, simply print the least number of hours Blackbeard needs to collect all his treasure and return to the landing point. If it is impossible to reach all the treasures, print out -1.

Sample Input

7 7
~~~~~~~
~#!###~
~...#.~
~~....~
~~~.@~~
.~~~~~~
...~~~.
10 10
~~~~~~~~~~
~~!!!###~~
~##...###~
~#....*##~
~#!..**~~~
~~....~~~~
~~~....~~~
~~..~..@~~
~#!.~~~~~~
~~~~~~~~~~
0 0

Output for sample input

10
32


Broderick Arneson

題目描述:


海盜黑鬍子要取回寶藏,收集所有寶藏後走回原來的點,盤面上最多 10 個寶藏。

途中不能經過水路,也不能通過叢林,陸地上的原住民會攻擊!

黑鬍子只能走上下左右,但是原住民卻鄰近八個方格攻擊其他敵人。

題目解法:


請小心只有 1 個點的 TSP。

當然有可能寶藏在原住民的攻擊範圍內,因此答案一定是 impossible。

加上出發點總共是 11 個點的 TSP,請注意記憶體。

#include <stdio.h>
#include <string.h>
#include <queue>
#include <algorithm>
using namespace std;
char g[55][55], cannot[55][55];
int ng[55][55], used[55][55], h, w;
int dp[1<<12][12];
int dist[12][12];
void bfs(int x, int y) {
    queue<int> X, Y;
    int i, j, tx, ty;
    int dx[] = {0,0,1,-1};
    int dy[] = {1,-1,0,0};
    X.push(x), Y.push(y);
    memset(used, 0, sizeof(used));
    int st = ng[x][y];
    if(cannot[x][y])    return;
    while(!X.empty()) {
        x = X.front(), X.pop();
        y = Y.front(), Y.pop();
        for(i = 0; i < 4; i++) {
            tx = x+dx[i], ty = y+dy[i];
            if(tx < 0 || ty < 0 || tx >= h || ty >= w)
                continue;
            if(cannot[tx][ty])    continue;
            if(g[tx][ty] == '!' || g[tx][ty] == '.') {
                if(used[tx][ty] == 0) {
                    used[tx][ty] = used[x][y]+1;
                    X.push(tx), Y.push(ty);
                    if(g[tx][ty] == '!')
                        dist[st][ng[tx][ty]] = used[x][y]+1;
                }
            }
        }
    }   
}
int dfs(int state, int last, int n) {
    int &ret = dp[state][last];
    if(ret != -1)    return ret;
    if(state == 0)
        return dist[last][0];
    ret = 0xfffffff;
    int i;
    for(i = 0; i < n; i++) {
        if((state>>i)&1) {
            ret = min(ret, dfs(state^(1<<i), i, n)+dist[last][i]);
        }
    }
    return ret;
}
int main() {
    int i, j, k;
    while(scanf("%d %d", &h, &w) == 2 && h+w) {
        for(i = 0; i < h; i++)
            scanf("%s", g[i]);
        memset(dp, -1, sizeof(dp));
        memset(cannot, 0, sizeof(cannot));
        int n = 0;
        int dx[] = {0,0,1,1,1,-1,-1,-1};
        int dy[] = {1,-1,0,1,-1,0,1,-1};
        int tx, ty;
        for(i = 0; i < h; i++) {
            for(j = 0; j < w; j++) {
                if(g[i][j] == '@')    g[i][j] = '!';
                if(g[i][j] == '!')
                    ng[i][j] = n++;
                if(g[i][j] == '*') {
                    for(k = 0; k < 8; k++) {
                        tx = i+dx[k], ty = j+dy[k];
                        if(tx < 0 || ty < 0 || tx >= h || ty >= w)
                            continue;
                        cannot[tx][ty] = 1;
                    }
                }
                if(g[i][j] == '~')    cannot[i][j] = 1;
                if(g[i][j] == '#')    cannot[i][j] = 1;
            }
        }
        for(i = 0; i < n; i++) {
            for(j = 0; j < n; j++)
                dist[i][j] = 0xfffffff;
        }
        for(i = 0; i < h; i++) {
            for(j = 0; j < w; j++) {
                if(g[i][j] == '!')
                    bfs(i, j);
            }
        }
        int ret = dfs((1<<n)-1-1, 0, n);
        if(ret == 0xfffffff)    ret = -1;
        if(n == 1)                ret = 0;
        printf("%d\n", ret);
    }
    return 0;
}

台長: Morris
人氣(1,525) | 回應(0)| 推薦 (0)| 收藏 (0)| 轉寄
全站分類: 教育學習(進修、留學、學術研究、教育概況) | 個人分類: UVA |
此分類下一篇:[UVA][TSP] 11405 - Can U Win?
此分類上一篇:[UVA][二分貪婪] 12255 - Underwater Snipers

是 (若未登入"個人新聞台帳號"則看不到回覆唷!)
* 請輸入識別碼:
請輸入圖片中算式的結果(可能為0) 
(有*為必填)
TOP
詳全文