7-11 Saving James Bond - Hard Version (30 分)

7-11 Saving James Bond - Hard Version (30 分)

原題鏈接:https://pintia.cn/problem-sets/16/problems/673
這道題本質是就是一道BFS,只不過要加上路徑。
 開始做的時候比較順利,但是總是有一個測試點沒過去,找了半天還是找不到錯誤。於是google一下,發現是沒仔細看題。
 題目中說,當有多條最短路徑時,選擇第一跳最短的。我竟然麼看見(😭😭找了兩個多小時)。處理第一條最短,比較簡單的做法時我們在用BFS,一開始把鱷魚入隊時,就把順序排好,這樣出來的一定是最終的結果。

思路:

在處理能不能在兩個鱷魚之間跳時,一是可以先計算好能不能跳,然後直接在BFS裏用結果。二是在BFS的過程中,判斷能不能跳。
其實我個人比較推薦第二種,沒必要先計算好,現算現用就行。不過如果計算的結構要多次使用的話,保存下來了比較好。

代碼:
#include <iostream>
#include <algorithm>
#include <queue>
#include <cmath>
using namespace std;
const int MAX = 110;
const int INFO = 1000000;
struct Node{
    int X,Y;
    Node() {} //用來不初始化定義Ver[101]
    Node(int _x,int _y) : X(_x),Y(_y) {} //用來提供X和Y的初始值
}Ver[MAX];
int Path[MAX]; //記錄路徑
int N,D;
bool book[MAX]; //記錄是否訪問
int last = -1;
queue<int> q;
bool IsVertexJump(int a,int b){ //能不能從a到b
    return (pow(Ver[a].X-Ver[b].X,2) + pow(Ver[a].Y-Ver[b].Y,2) <= pow(D,2));
}
bool IsSave(int a){ //a能不能到岸
    return (pow(Ver[a].X,2) <= pow(D,2) || pow(Ver[a].Y,2) <= pow(D,2) || \
        pow(100-Ver[a].X,2) <= pow(D,2) || pow(100-Ver[a].Y,2) <= pow(D,2));
}
int IsCenterJump(int a){ //能不能從中心跳出
    if(pow(Ver[a].X-50,2) + pow(Ver[a].Y-50,2) <= pow(D + 7.5,2))
        return (pow(Ver[a].X-50,2) + pow(Ver[a].Y-50,2));
    else 
        return 0;
}
bool cmp(int x,int y){ //排序的比較函數
    return IsCenterJump(x)<IsCenterJump(y);
}
void Save007(){ //無權圖單源最短路
    int temp;
    int b[MAX]; //用來把第一跳排序
    fill(Path, Path+N+1, INFO);
    fill(book, book+N+1, false);
    Path[0] = -1;
    book[0] = true;
    if(IsSave(0)){
        last = 0;
        return;
    }
    for(int i=1;i<=N;i++){ //對第一跳排序
        b[i] = i;
    }
    sort(b+1,b+N+1,cmp); //why 第二個是N + 1
    for(int i=1;i<=N;i++){ //按靠近center的順序,放入queue
        if(IsCenterJump(b[i])){
            q.push(b[i]);
            Path[b[i]] = 0;
            book[b[i]] = true;
        }
    }
    while(!q.empty()){
        temp = q.front();
        q.pop();
        if(IsSave(temp)){ //能不能到岸
            last = temp;
            break;
        } 
        for(int i=1;i<=N;i++){
            if(!book[i] && IsVertexJump(temp,i)){
                q.push(i);
                Path[i] = temp;
                book[i] = true; //在入隊時就book
            }
        }
    }
}
int main(){
    int x,y;
    int a[MAX]; //記錄最短路徑
    int count = 0;
    Ver[0] = Node(50,50);
    scanf("%d%d",&N,&D);
    for(int i=1;i<=N;i++){
        scanf("%d%d",&x,&y);
        Ver[i] = Node(x+50,y+50);
    }
    Save007();
    if(last == -1) printf("0\n");//輸出結果
    else {
        while(last > 0){
            a[count++] = last;
            last = Path[last];
        }
        printf("%d\n",count+1);
        for(int i=count-1;i>=0;i--){
            printf("%d %d\n",Ver[a[i]].X-50,Ver[a[i]].Y-50);
        }
    }
    system("pause");
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章