ICPC North America Qualifier Contest 2015 K. UnDetected(并查集)

The Department of Defense has been designing autonomous robots that can infiltrate war zones and other hostile places in order to carry out missions. Now they want to test their latest design, the Penetrator17001700, and they've hired you to help design the test environment.

The test environment is a rectangular field with some sensors placed within the field. Each sensor has a certain radius defining the region within which it can detect a robot. You want to design the field to have as many sensors as possible while still permitting a route across the field that avoids detection.

The field is a region of the coordinate plane defined by 0\leq x \leq 2000≤x≤200 and 0 \leq y \leq 3000≤y≤300. The robot can be modeled by a point that must remain on the field at all times. It starts at the bottom of the field (y = 0)(y=0) and must end at the top of the field (y = 300)(y=300), and must not pass within range of any sensor. There are NN sensor locations given by triples (x,y,r)(x,y,r) of integers, where each (x,y)(x,y) is a point on the field, and rr is its radius of detection. The implied sensor circles may overlap, but will never be tangent with each other nor with the boundary of the field. All sensors are initially inactive. You must find the largest value of kk such that if sensors 1,2,3,\dots,k1,2,3,…,k are activated there is a path for the robot across the field, but no path if the (k+1)\text{st}(k+1)st sensor is also activated. It is guaranteed that there is no path if all NN sensors are activated.

K2.png

Input

Input begins with a positive integer N \leq 200N≤200. Each of the next NN lines has three space-separated integers, representing x,y,rx,y,r for a sensor, where r \leq 300r≤300. All sensors lie at different (x,y)(x,y) positions. The first three sample inputs below correspond to the figure shown.

Output

Output a single integer (which may be 00) giving the largest kk as described above.

Since the task has 4 samples, PDF is recommended.

输出时每行末尾的多余空格,不影响答案正确性

样例输入1复制

6
36 228 58
164 224 58
88 170 42
93 105 42
167 85 58
28 44 58

样例输出1复制

2

样例输入2复制

6
36 228 58
28 44 58
164 224 58
88 170 42
93 105 42
167 85 58

样例输出2复制

3

样例输入3复制

6
28 44 58
36 228 58
88 170 42
93 105 42
164 224 58
167 85 58

样例输出3复制

4

题意:

现有一个矩形区域:x = 0 到 x = 200, y = 0 到 y = 300。机器人想要从 y = 0 处移动到 y = 300 处,有 n 个传感器按顺序打开,传感器覆盖的区域机器人不能通过,问最多打开多少个传感器,使得机器人还能通过。保证传感器覆盖区域不相切。

思路:

并查集判断左右两边界的连通性

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const double eps = 1e-10;
const int inf = 0x3f3f3f3f;
const int N = 205;

int n, fa[N];

struct node
{
    int x, y, r;
} s[N];

bool judge(int i, int j)
{
    if(j == 1)
    {
        if(-s[i].r < s[i].x && s[i].x < s[i].r)
            return 1;
        else
            return 0;
    }
    else if(j == 2)
    {
        if(200 - s[i].r < s[i].x && s[i].x < 200 + s[i].r)
            return 1;
        else
            return 0;
    }
    else
    {
        int x1 = s[i].x;
        int y1 = s[i].y;
        int x2 = s[j].x;
        int y2 = s[j].y;
        if((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) < (s[i].r + s[j].r) * (s[i].r + s[j].r))
            return 1;
        else
            return 0;
    }
}

void init()
{
    for(int i = 1; i <= n + 2; ++i)
    {
        fa[i] = i;
    }
}

int Find(int x)
{
    if(fa[x] != x)
    {
        fa[x] = Find(fa[x]);
    }
    return fa[x];
}

void unionn(int x, int y)
{
    int xx = Find(x);
    int yy = Find(y);
    if(xx != yy)
    {
        fa[xx] = yy;
    }
}

int main()
{
    int x, y, r, cnt;
    scanf("%d", &n);
    init();
    for(int i = 3; i <= n + 2; ++i)
    {
        scanf("%d%d%d", &s[i].x, &s[i].y, &s[i].r);
    }
    bool flag = 0;
    for(int i = 3; i <= n + 2; ++i)
    {
        for(int j = 1; j < i; ++j)
        {
            if(judge(i, j))
            {
                unionn(i, j);
            }
        }
//        cout<<Find(1)<<' '<<Find(2)<<'\n';
        if(Find(1) == Find(2))
        {
            cnt = i - 3;
            flag = 1;
            break;
        }
    }
    if(!flag)
        cnt = n;
    cout<<cnt<<'\n';
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值