您的位置:首页 > 编程语言 > PHP开发

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

2016-04-26 10:03 791 查看
有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
;
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
;
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
;
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: