pta拯救007

題目詳情:

在老電影“007之生死關頭”(Live and Let Die)中有一個情節,007被毒販抓到一個鱷魚池中心的小島上,他用了一種極爲大膽的方法逃脫 —— 直接踩着池子裏一系列鱷魚的大腦袋跳上岸去!(據說當年替身演員被最後一條鱷魚咬住了腳,幸好穿的是特別加厚的靴子才逃過一劫。)
設鱷魚池是長寬爲100米的方形,中心座標爲 (0, 0),且東北角座標爲 (50, 50)。池心島是以 (0, 0) 爲圓心、直徑15米的圓。給定池中分佈的鱷魚的座標、以及007一次能跳躍的最大距離,你需要告訴他是否有可能逃出生天。

輸入格式:

首先第一行給出兩個正整數:鱷魚數量 N(≤100)和007一次能跳躍的最大距離 D。隨後 N 行,每行給出一條鱷魚的 (x,y) 座標。注意:不會有兩條鱷魚待在同一個點上。

輸出格式:

如果007有可能逃脫,就在一行中輸出”Yes”,否則輸出”No”。

輸入樣例 1:

14 20
25 -15
-25 28
8 49
29 15
-35 -2
5 28
27 -29
-8 -28
-20 -35
-25 -20
-13 29
-30 15
-35 40
12 12

輸出樣例 1:

Yes

輸入樣例 2:

4 13
-12 12
12 12
-12 -12
12 -12

輸出樣例 2:

No

題目思路:

這道題目的解題中使用到了dfs和圖的相關知識,

p[]是所輸入的每個節點的數組(鱷魚的集合)

vis[]是判斷是否該節點被訪問:

如果被訪問過了,那麼只有兩種情況:1.找到出口,直接彈出(break)。2.沒有出口~

所以如果節點被訪問過,就意味着該節點不是出口。

另外注意我們還有對於第一次的中心島的特殊判斷,他的距離與其他的dfs過程不同。

#include<bits/stdc++.h>
using namespace std;
int n,d;
    struct node//定義節點(存儲x,y座標)
{ 
    int x;
    int y;
}p[110];  
bool vis[110];
bool flag =0;
bool first(int i){//判斷該節點是否可以在第一次可以跳出中心島(即判斷該點是否在第一次跳出的半徑內)
    return(p[i].x*p[i].x+p[i].y*p[i].y <= (d+7.5)*(d+7.5));
}
bool success(int i){//判斷能否在該結點處一次直接跳出(d>0),分別判斷x,y是否可以跳出邊界(即能否一步上岸)
    return p[i].x-d<=-50||p[i].x+d>=50||p[i].y+d>=50||p[i].y-d<=-50;
}
bool isJump(int i,int j){//判斷是否可以從一點跳到另一點
    return (p[i].x*p[i].x+p[i].y*p[i].y)<d*d;
}
int dfs(int i){//遞歸,dfs判斷是否可以找到出去的路
    vis[i] = 1;//表示已經訪問該節點
    if(success(i))return 1;
    for(int j=0;j<n;j++){//遍歷尋找節點
        if(!vis[j]&&isJump(i,j))
        {//如果該點訪問過,那麼此路就代表不通,應該放棄這個點;同時我們還要找到可以跳躍過去的點。
        if(dfs(j))return 1;
        }
    }
    return false;
}

int main(){
    
    cin>>n>>d;
    for(int i=0;i<n;i++){
        cin>>p[i].x>>p[i].y;
    }
    if(d>=42.5)flag = true;
    else {
        for(int i=0;i<n;i++){//應該通過遍歷找到符合條件的節點
            if(!vis[i]&&first(i))//如果沒有訪問過這個節點,且在第一次跳出的半徑內。
                if(dfs(i)){
                    flag =1;
                    break;//跳出並不再尋找
                }
        }

    }
    if(flag)cout<<"yes";
    else cout<<"no";

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