传送门
题面:
J. The Volcano Eruption
time limit per test
5.0 s
memory limit per test
64 MB
input
standard input
output
standard output
"The volcano erupted!". Shouted Shahhoud, as he was attempting to wake Saeed up.
"You need to save Noor, he is trapped in the lab next to the volcano!". Shahhoud said.
You can picture the road between the base and the lab as a rectangle whose bottom left corner is at (0, 0) and top right corner is at (W, L). There are n holes filled with lava from the volcano. The ith hole is a circle whose center is at coordinates (xi, yi) and has a radius of ri. The holes may intersect to make larger holes.
Saeed Starts his mission at any point on the bottom side of the rectangle ( any point (0...W, 0)), and has to reach any point on the top side of the rectangle ( any point (0...W, L)), in order to save Noor.
None of the holes intersect with the bottom or the top sides of the rectangle ( the starting and finishing line).
Saeed can take special suits in his anti-lava backpack. Each special suit allows him to swim in one or more intersecting holes (once he goes out of the lava onto the street, he has to throw away the suit). Saeed must stay inside the street at all times. Please note that if two holes are touching each other by the border, then Saeed can't walk from between them without wearing a special suit.
What is the minimum number of suits Saeed has to take with him in order to reach the lab and save Noor?
Input
The first line contains a single integer T, the number of test cases. The first line of each test case contains 3 integers N,W, and L. The number of holes, the width, and the length of the rectangle. (1 ≤ N ≤ 1000) (1 ≤ W, L ≤ 109) Each of the following N lines contain 3 integers (0 ≤ xi ≤ W), (0 < yi < L), and (1 ≤ ri ≤ 109), the coordinates and radius of the ith hole. It's guaranteed that none of the holes intersect with the bottom or the top sides of the rectangle ( the starting and finishing line).
Output
For each test case, output a single line containing a single integer, the minimum number of suits Saeed must take with him to save Noor.
Example
input
Copy
1 5 5 18 4 2 1 2 12 3 4 6 2 2 6 1 1 7 1
output
Copy
2
Note
The figure below shows a possible solution for the sample.
题意:
有一个长度为L,宽度为W的长方形区间。一共有n个圆,这n个圆可能两两相交,当你进入圆的区域的时候,你需要换一次衣服;而当你走出圆的领域的时候,你也需要换一次衣服。现在问你,在不能走出长方形区间的前提下,你最少需要换多少次衣服。
题目分析:
拿到题目一看,貌似需要处理一堆圆相交的问题,貌似处理起来非常困难。
但是如果我们再深入观察的话,我们可以发现,对于一个圆,倘若它恰好在长方形区间内部(与长方形没有交点),则我们可以从两边绕过这块区间。因此,当且仅当存在一个圆,它的最左端覆盖掉长方形左边,最右端覆盖掉长方形右边,此时,我们必须经过该圆。因此我们只需要处理出左右边界的情况即可。
而因为可能存在多个圆相交的情况,此时,我们可以将相交的圆看成一个整体,用并查集对这一块区间进行维护,最后处理一下左右边界情况统计答案即可。
代码:
#include <bits/stdc++.h>
#define maxn 1005
using namespace std;
typedef long long ll;
struct Node{
ll x,y,r;
}q[maxn];
bool Intertion(Node a,Node b){
ll tmp=(a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
ll rr=(a.r+b.r)*(a.r+b.r);
if(tmp>rr) return 0;
else return 1;
}
int Far[maxn];
int Find_F(int x){//并查集
if(Far[x]==x) return x;
else return Far[x]=Find_F(Far[x]);
}
void unite(int x,int y){
x=Find_F(x),y=Find_F(y);
if(x==y) return ;
else Far[x]=y;
}
int Left[maxn],Right[maxn];//左边界和右边界的情况
void init(int n){
for(int i=0;i<=n;i++){
Far[i]=i;
Left[i]=Right[i]=0;
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--){
ll n,w,l;
scanf("%lld%lld%lld",&n,&w,&l);
init(n);
for(int i=0;i<n;i++){
scanf("%lld%lld%lld",&q[i].x,&q[i].y,&q[i].r);
}
for(int i=0;i<n;i++){
for(int j=0;j<i;j++){//用并查集去维护相交的圆
if(Intertion(q[i],q[j])) unite(i,j);
}
}
for(int i=0;i<n;i++){//分别维护左右边界
if(q[i].x-q[i].r<=0) Left[Find_F(i)]=1;
if(q[i].x+q[i].r>=w) Right[Find_F(i)]=1;
}
int ans=0;
for(int i=0;i<n;i++){//如果左右边界都被某个圆集合覆盖,则增加答案
if(Find_F(i)==i&&Left[Find_F(i)]==1&&Right[Find_F(i)]==1) ans++;
}
printf("%d
",ans);
}
}