POJ 3968|UVALive 4992|HDU 3761|UVA 1475|Jungle Outpost|二分|半平面交

33 篇文章 0 订阅

有n个瞭望台,形成一个凸的n多边形。瞭望台的保护范围就是凸多边形内。敌人进攻会炸毁一些瞭望台使得总部暴露在剩下瞭望台凸包之外。你的任务是选择一个点作为总部使得最少需要炸坏的瞭望台总数尽可能多。输出此时敌人需要炸毁的瞭望台数量。

vjudge真是个好地方,4倍经验唾手可得

一开始想了个 O(n2) 的真是作死。。
n 这么大应该是O(nlogn)的。
二分答案。
发现敌人最少炸坏的瞭望台总是在凸包上是连续的,否则总是可以调整成这种模式。

#include <cstdio>
#include <cmath>
#include <algorithm>
#define FOR(i,j,k) for(i=j;i<=k;i++)
using namespace std;
const int N = 100005;
typedef long double ld;
struct Point {
    ld x, y;
    Point() { }
    Point(ld _x, ld _y) : x(_x), y(_y) { }
    Point operator+ (const Point &b) const { return Point(x + b.x, y + b.y); }
    Point operator- (const Point &b) const { return Point(x - b.x, y - b.y); }
    ld operator* (const Point &b) const { return x * b.y - y * b.x; }
    Point operator* (ld b) const { return Point(b * x, b * y); }
} p[N];
struct Line {
    Point x, v;
    ld ang;
    Line() { }
    Line(const Point &a, const Point &b) {
        x = a; v = b - a;
        ang = atan2(v.y, v.x);
    }
    bool operator< (const Line &b) const {
        if (ang == b.ang) return v * (b.x - x) < 0;
        return ang < b.ang;
    }
    bool operator== (const Line &b) const { return ang == b.ang; }
    Point intersection(const Line &b) {
        Point u = x - b.x;
        ld t = (b.v * u) / (v * b.v);
        return x + v * t;
    }
} line[N];
bool right(const Point &p, const Line &l) {
    return l.v * (p - l.x) < 0;
}
bool half_plane_intersection(Line l[], int n) {
    static Line q[N];
    sort(l, l + n);
    int f = 0, r = 0, i;
    q[r++] = l[0]; q[r++] = l[1];
    for (i = 2; i < n; i++) {
        while (f < r && right(q[r].intersection(q[r - 1]), l[i])) --r;
        while (f < r && right(q[f].intersection(q[f + 1]), l[i])) ++f;
        q[r++] = l[i];
    }
    while (f < r && right(q[r].intersection(q[r - 1]), q[f])) --r;
    while (f < r && right(q[f].intersection(q[f + 1]), q[r])) ++f;
    return r - f <= 1;
}
int main() {
    int i, a, b, l, r, mid, ans = -1, n;
    while (scanf("%d", &n) != EOF) {
        for (i = 0; i < n; ++i) {
            scanf("%d%d", &a, &b);
            p[i] = Point(a, b);
        }
        for (l = 1, r = n - 3, ans = n - 2; l <= r; ) {
            mid = l + r >> 1;
            for (i = 0; i < n; ++i)
                line[i] = Line(p[(i + mid + 1) % n], p[i]);
            if (half_plane_intersection(line, n)) r = mid - 1, ans = mid;
            else l = mid + 1;
        }
        printf("%d\n", ans);
    }
    return 0;
}

Jungle Outpost

Time Limit: 40000/20000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1194 Accepted Submission(s): 277

Problem Description

There is a military base lost deep in the jungle. It is surrounded by n watchtowers with ultrasonic generators. In this problem watchtowers are represented by points on a plane.
Watchtowers generate ultrasonic field and protect all objects that are strictly inside the towers’ convex hull. There is no tower strictly inside the convex hull and no three towers are on a straight line.
The enemy can blow up some towers. If this happens, the protected area is reduced to a convex hull of the remaining towers.

The base commander wants to build headquarters inside the protected area. In order to increase its security, he wants to maximize the number of towers that the enemy needs to blow up to make the headquarters unprotected.

Input

The input begins with an integer T. The next T blocks each represents a case. The first line of each case contains a single integer n (3 ≤ n ≤ 50 000) - the number of watchtowers. The next n lines contain the Cartesian coordinates of watchtowers, one pair of coordinates per line. Coordinates are integer and do not exceed 106 by absolute value. Towers are listed in the order of traversal of their convex hull in clockwise direction.

Output

For each case, write to the output the number of watchtowers the enemy has to blow up to compromise headquarters protection if the headquarters are placed optimally.

Sample Input

2
3
0 0
50 50
60 10
5
0 0
0 10
10 20
20 10
25 0

Sample Output

1
2

Author

Pavel Mavrin

Source

2010 Northeastern European Regional Contest

Recommend

notonlysuccess

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值