UVa 1475 (二分+半平面交) Jungle Outpost
题意:
有n个瞭望塔构成一个凸n边形,敌人会炸毁一些瞭望台,剩下的瞭望台构成新的凸包。在凸多边形内部选择一个点作为总部,使得敌人需要炸毁的瞭望塔最多才能使总部暴露出来。输出敌人需要炸毁的数目。
分析:
在炸毁同样数量的瞭望塔时,如何爆破才能使暴露出的面积最大。那就是集中火力炸掉连续的几个瞭望塔。直觉上是这样的,我不会证明这个结论。因为是连续爆破,所以k次爆破后还保留的部分就是一个半平面,枚举这k个爆破点,如果这些半平面交非空则总部可以设在这里。
k值是通过二分来确定的,下界是1,上界是n-3(这个需要好好想一下,想不清楚的话即使写n应该也可以)。
//#define LOCAL
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
using namespace std; const int maxn = + ;
const double eps = 1e-;
typedef long long LL; void scan( int &x )
{
char c;
while( c = getchar(), c < '' || c > '' );
x = c - '';
while( c = getchar(), c >= '' && c <= '' ) x = x* - c + '';
} struct Point
{
double x, y;
Point(double x=, double y=):x(x), y(y) {}
};
typedef Point Vector;
Point operator + (const Point& a, const Point& b) { return Point(a.x+b.x, a.y+b.y); }
Point operator - (const Point& a, const Point& b) { return Point(a.x-b.x, a.y-b.y); }
Vector operator * (const Vector& a, double p) { return Vector(a.x*p, a.y*p); }
double Dot(const Vector& a, const Vector& b) { return a.x*b.x + a.y*b.y; }
double Cross(const Vector& a, const Vector& b) { return a.x*b.y - a.y*b.x; }
double Length(const Vector& a) { return sqrt(Dot(a, a)); }
Vector Normal(const Vector& a)
{
double l = Length(a);
return Vector(-a.y/l, a.x/l);
} double PolygonArea(const vector<Point>& p)
{
int n = p.size();
double ans = 0.0;
for(int i = ; i < n-; ++i)
ans += Cross(p[i]-p[], p[i+]-p[]);
return ans/;
} struct Line
{
Point P;
Vector v;
double ang;
Line() {}
Line(Point p, Vector v):P(p), v(v) { ang = atan2(v.y, v.x); }
bool operator < (const Line& L) const
{
return ang < L.ang;
}
}; bool OnLeft(const Line& L, Point p)
{
return Cross(L.v, p-L.P) > ;
} Point GetLineIntersection(const Line& a, const Line& b)
{
Vector u = a.P - b.P;
double t = Cross(b.v, u) / Cross(a.v, b.v);
return a.P + a.v*t;
} vector<Point> HalfplaneIntersection(vector<Line>& L)
{
int n = L.size();
//sort(L.begin(), L.end()); vector<Point> p(n);
vector<Line> q(n);
vector<Point> ans;
int first, last; q[first=last=] = L[];
for(int i = ; i < n; ++i)
{
while(first < last && !OnLeft(L[i], p[last-])) last--;
while(first < last && !OnLeft(L[i], p[first])) first++;
q[++last] = L[i];
if(fabs(Cross(q[last].v, q[last-].v)) < eps)
{
last--;
if(OnLeft(q[last], L[i].P)) q[last] = L[i];
}
if(first < last) p[last-] = GetLineIntersection(q[last], q[last-]);
}
while(first < last && !OnLeft(q[first], p[last-])) last--;
if(last-first <= ) return ans;
p[last] = GetLineIntersection(q[first], q[last]); for(int i = first; i <= last; ++i) ans.push_back(p[i]);
return ans;
} Point p[maxn];
int n; bool check(int m)
{
vector<Line> lines;
for(int i = ; i < n; ++i)
lines.push_back(Line(p[(i+m+)%n], p[i]-p[(i+m+)%n]));
return HalfplaneIntersection(lines).empty();
} int solve()
{
if(n==) return ;
int L = , R = n-, M;
while(L < R)
{
M = L + (R-L)/;
if(check(M)) R = M;
else L = M+;
}
return L;
} int main(void)
{
#ifdef LOCAL
freopen("4992in.txt", "r", stdin);
#endif int x, y;
while(scanf("%d", &n) == && n)
{
for(int i = ; i < n; ++i)
{
scanf("%d%d", &x, &y);
p[i] = Point(x, y);
}
printf("%d\n", solve());
} return ;
}
代码君
UVa 1475 (二分+半平面交) Jungle Outpost的更多相关文章
- [HNOI2012][BZOJ2732] 射箭 [二分+半平面交]
题面 BZOJ题面 思路 半平面交代码讲解戳这里,用的就是这道题 我们射箭的函数形如$y=Ax^2+Bx$ 考虑每一个靶子$(x_0,y_1,y_2)$,实际上是关于$A,B$的不等式限制条件 我们只 ...
- poj 3525Most Distant Point from the Sea【二分+半平面交】
相当于多边形内最大圆,二分半径r,然后把每条边内收r,求是否有半平面交(即是否合法) #include<iostream> #include<cstdio> #include& ...
- 二分+半平面交——poj1279
/* 二分距离,凸包所有边往左平移这个距离,半平面交后看是否还有核存在 */ #include<iostream> #include<cstring> #include< ...
- POJ 3525/UVA 1396 Most Distant Point from the Sea(二分+半平面交)
Description The main land of Japan called Honshu is an island surrounded by the sea. In such an isla ...
- POJ3525:Most Distant Point from the Sea(二分+半平面交)
pro:给定凸多边形,求凸多边形内的点到最近边界的最远距离. sol:显然是二分一个圆,使得圆和凸多边形不相交,但是这样很难实现. 由于是凸多边形,我们可以把二分圆转化为二分凸多边形的移动. 如果每一 ...
- POJ3525-Most Distant Point from the Sea(二分+半平面交)
Most Distant Point from the Sea Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 3955 ...
- poj3525Most Distant Point from the Sea(半平面交)
链接 求凸多边形内一点距离边最远. 做法:二分+半平面交判定. 二分距离,每次让每条边向内推进d,用半平面交判定一下是否有核. 本想自己写一个向内推进..仔细一看发现自己的平面交模板上自带.. #in ...
- UVALive 4992 Jungle Outpost(半平面交判存)
Jungle Outpost Time limit: 15.000 seconds Description There is a military base lost deep in the jung ...
- LA 4992 Jungle Outpost(半平面交)
Jungle Outpost [题目链接]Jungle Outpost [题目类型]半平面交 &题解: 蓝书282 我自己写的代码居然AC了!!! 刘汝佳的说要right要-3什么的,还要特判 ...
随机推荐
- WPF 多线程处理(3)
WPF 多线程处理(1) WPF 多线程处理(2) WPF 多线程处理(3) WPF 多线程处理(4) WPF 多线程处理(5) WPF 多线程处理(6) 首先我们需要几个属性来保存取得的数据,因为在 ...
- Careercup - Facebook面试题 - 6321181669982208
2014-05-02 09:40 题目链接 原题: Given a number N, write a program that returns all possible combinations o ...
- How to use Android Activity's finish(), onDestory() and System.exit(0) methods
Activity.finish() Calling this method will let the system know that the programmer wants the current ...
- Openmeeting 网页打开缓慢,视频卡的一个解决方法
在初次安装完openmeeting以后,从浏览器打开后发现网页缓慢,视频有卡顿的现象. 原因:为openmeeting分配的内存太小. 解决方法: 找到根目录的red5.bat,打开后查找“set J ...
- c++ 信号量
最近写了个c++项目,发现 ctrl + c 退出程序可以出发析构,但kill pid,则不会触发析构,导致现场数据丢失. 解决方案:同时捕捉以下信号. signal(SIGINT, &完成命 ...
- QC缺陷管理操作-细说(转)
一.缺陷常用字段说明 二.缺陷管理流程图 三.开发人员修改缺陷填写规范 四.项目经理决定延期修改缺陷 一.缺陷常用字段说明 1.摘要 对缺陷的简单描述.摘要包括该缺陷所属的模块名称-子模块名称,以及简 ...
- yum源万能
sed -i ‘s|^#baseurl|baseurl| ; s|^mirrorlist|#mirrorlist|’ /etc/yum.repos.d/*
- 如何通过热修复,搞定开发中的那些 Bug?
作为程序员,Bug 修复终究是绕不开的话题,本期移动开发精英俱乐部讨论的主题便是 Bug 修复中的 Hotfix,即热修复.接下来让我们跟随大牛的脚步来了解 Hotfix,就算你不能一下豁然开朗,相信 ...
- Oracle 6 - 锁
Oracle锁没有额外的开销?Oracle的锁是怎么实现的?因为其他数据库,锁都是一种稀有资源和开销. 答:代码级实现?? 没有锁的话,并发更新就会有丢失更新的问题. 悲观锁和乐观锁 悲观锁一般用于有 ...
- lintcode :Permutation Index 排列序号
题目: 排列序号 给出一个不含重复数字的排列,求这些数字的所有排列按字典序排序后该排列的编号.其中,编号从1开始. 样例 例如,排列[1,2,4]是第1个排列. 解题: 这个题目感觉很坑的.感觉这只有 ...