描述
作爲H國的精英特工,你接到了一項任務,駕駛一輛吉普穿越佈滿監測雷達的禁區。爲了簡化題目,我們可以把禁區想象爲一個左下角是(0, 0)右上角是( W, H )的長方形區域。區域中一共有 N 座雷達,其中第 i 座的座標是(Xi,Yi ),監測範圍是半徑爲 Ri 的圓形區域。所有在圓內和圓上的運載工具都會被監測到。
你的目標是從左到右穿越禁區。你可以選擇線段(0, 0)-(0, H)上任意一點作爲起點,線段(W, 0)-(W, H)上任意一點作爲終點。在禁區內你可以沿任意路線行駛,只要保持始終在禁區內並且沒有被雷達監測到。
給出禁區內的雷達部署方案,你需要判斷是否存在滿足條件的行駛路線。
輸入
輸入包含多組數據。
第1行是一個整數 T,表示以下有 T 組數據 (1 ≤ T ≤ 10)。
每組數據的第1行:三個整數 W, H, N (0 ≤ W, H ≤ 1000000, 1 ≤ N ≤ 1000)。
每組數據的第2-N+1行:每行三個整數Xi, Yi, Ri (0 ≤ Xi ≤ W, 0 ≤ Yi ≤ H, 1 ≤ Ri ≤ 1000000)。
輸出
對於每組數據輸出"YES"或者"NO"表示是否有滿足條件的行駛路線。
2 10 4 2 5 1 1 5 3 1 10 4 2 5 1 1 6 3 1樣例輸出
NO YES
#include <stdio.h>
int graph[1024][1024];
int x[1024], y[1024], r[1024];
void build_graph(int N) {
int nein[1024] = {0};
for (int i = 0; i < N; ++i) {
for (int j = i + 1; j < N; ++j) {
long long dx = x[i] - x[j], dy = y[i] - y[j], sr = r[i] + r[j];
if (dx * dx + dy * dy <= sr * sr) {
graph[i][nein[i]] = j;
graph[j][nein[j]] = i;
nein[i]++;
nein[j]++;
}
}
}
for (int i = 0; i < N; ++i)
graph[i][nein[i]] = -1;
}
int dfs(int i, int* done) {
done[i] = 1;
if (y[i] - r[i] <= 0)
return 1;
for (int k = 0; graph[i][k] != -1; ++k) {
int j = graph[i][k];
if (done[j] == 0)
if (dfs(j, done))
return 1;
}
return 0;
}
int main() {
int T, W, H, N;
scanf("%d", &T);
for (int t = 0; t < T; ++t) {
scanf("%d%d%d", &W, &H, &N);
for (int i = 0; i < N; ++i)
scanf("%d%d%d", &(x[i]), &(y[i]), &(r[i]));
build_graph(N);
int done[1024] = {};
int find = 0;
for (int i = 0; i < N; ++i) {
if (y[i] + r[i] >= H) {
if (dfs(i, done)) {
find = 1;
printf("NO\n");
break;
}
}
}
if (find == 0)
printf("YES\n");
}
}
方法二: 並查集
#include<iostream>
#include<vector>
#include<algorithm>
#include<limits.h>
#include<set>
#include<math.h>
using namespace std;
int main()
{
vector<pair<int ,int> > vec;
int T, W, H, N, xi, yi, ri;
cin >> T;
while(T--)
{
cin >> W >> H >> N;
vector<vector<int> > radars;
for(int i = 0; i < N; i++)
{
cin >> xi >> yi >> ri;
radars.push_back(vector<int>{xi, yi, ri});
}
int ans = 1;
vector<int> hash(N);
for(int i = 0; i < N ;i++) hash[i] = i;
for(int i =0; i< N; i++)
{
int x1 = radars[i][0], y1 = radars[i][1], r1 = radars[i][2];
for(int j = i+1; j < N; j++)
{
int x2 = radars[j][0], y2 = radars[j][1], r2 = radars[j][2];
float dis = sqrt(pow(x1-x2, 2)+ pow(y1-y2, 2));
if(dis <= r1+r2)
{
int par1 = hash[j], par2 = hash[i];
while(hash[par1] != par1) par1 = hash[par1];
while(hash[par2] != par2) par2 = hash[par2];
hash[par1] = par2;
}
}
}
set<int> parent;
for(int i =0; i< N; i++)
{
int par = hash[i];
while(par != hash[par]) par = hash[par];
hash[i] = par;
parent.insert(par);
}
for(int val: parent)
{
int top = INT_MIN, bot = INT_MAX;
for(int i = 0; i < N; i++)
{
if(hash[i] == val)
{
top = max(top, radars[i][1] + radars[i][2]);
bot = min(bot, radars[i][1] - radars[i][2]);
if(top >= H && bot <=0)
{
ans = 0;
i = N;
break;
}
}
}
if(ans == 0) break;
}
if(ans) cout << "YES" << endl;
else cout << "NO" << endl;
}
return 0;
}