题意:

有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的更多相关文章

  1. [HNOI2012][BZOJ2732] 射箭 [二分+半平面交]

    题面 BZOJ题面 思路 半平面交代码讲解戳这里,用的就是这道题 我们射箭的函数形如$y=Ax^2+Bx$ 考虑每一个靶子$(x_0,y_1,y_2)$,实际上是关于$A,B$的不等式限制条件 我们只 ...

  2. poj 3525Most Distant Point from the Sea【二分+半平面交】

    相当于多边形内最大圆,二分半径r,然后把每条边内收r,求是否有半平面交(即是否合法) #include<iostream> #include<cstdio> #include& ...

  3. 二分+半平面交——poj1279

    /* 二分距离,凸包所有边往左平移这个距离,半平面交后看是否还有核存在 */ #include<iostream> #include<cstring> #include< ...

  4. 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 ...

  5. POJ3525:Most Distant Point from the Sea(二分+半平面交)

    pro:给定凸多边形,求凸多边形内的点到最近边界的最远距离. sol:显然是二分一个圆,使得圆和凸多边形不相交,但是这样很难实现. 由于是凸多边形,我们可以把二分圆转化为二分凸多边形的移动. 如果每一 ...

  6. POJ3525-Most Distant Point from the Sea(二分+半平面交)

    Most Distant Point from the Sea Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 3955   ...

  7. poj3525Most Distant Point from the Sea(半平面交)

    链接 求凸多边形内一点距离边最远. 做法:二分+半平面交判定. 二分距离,每次让每条边向内推进d,用半平面交判定一下是否有核. 本想自己写一个向内推进..仔细一看发现自己的平面交模板上自带.. #in ...

  8. UVALive 4992 Jungle Outpost(半平面交判存)

    Jungle Outpost Time limit: 15.000 seconds Description There is a military base lost deep in the jung ...

  9. LA 4992 Jungle Outpost(半平面交)

    Jungle Outpost [题目链接]Jungle Outpost [题目类型]半平面交 &题解: 蓝书282 我自己写的代码居然AC了!!! 刘汝佳的说要right要-3什么的,还要特判 ...

随机推荐

  1. window对象的属性方法名造成的命名冲突

    事件起因: 一次开发中需要获取一个数组的长度,写下如此代码 function func(arr){ length = arr.length; ......//相关操作 } 程序在chrome下正常运行 ...

  2. android聊天,存储聊天记录sqlite

    项目中有聊天模块,需要用到打开activity的时候初始化聊天记录的情况.大致情况如下: 辅助类:ChatSQLiteHelper   在第一次时会调用oncreate方法(判断的标准是schedul ...

  3. android手机推送视频到服务端

    项目需求,android手机向服务器推送视频.苦战几个星期终于实现,现记录下来以免以后忘记. 没做过Java,也没做过Android开发,只能现学现卖.在网上找了下搭建开发a  ndroid环境资料, ...

  4. Fixing:insert_modules not found

    搞linux的最怕的就是panic.满屏的报错不知头绪,百度出来的还都是抄来抄去的垃圾. 我遇到的错误已经解决,所以不想再看到报错了..google出来两个没有上下文的文本,因为和他们差不多,在下面贴 ...

  5. SpringJUnit4加载类目录下(src)和WEF-INF目录下的配置文件二--获取注入的bean的二种方式

    前言: spring容器以xml的形式注入bean,然后可以在类中获取,获取的形式主要有二种:第一种最简单--采用@Resource 或@Autowired关键字在加载spring文件时将bean注入 ...

  6. css3 怎么实现像书籍装订线的效果

    .test{ width: 150px; height: 150px; margin: 20% auto; background-color: white; background-image: rep ...

  7. 【HDOJ】【1693】Eat The Trees

    插头DP 插头dp模板题…… 这题比CDQ论文上的例题还要简单……因为不用区分左右插头(这题可以多回路,并不是一条哈密尔顿路) 硬枚举当前位置的状态就好了>_< 题解:http://blo ...

  8. sql2008安装时提示重启计算机失败解决方法

    安装sql 2008的时候,在检测安装环境中有一项是”重新启动计算机”显示的结果是“失败”.上网看了半天,找到了解决方案,虽然我没弄明白具体原因,但问题是解决了,解决方案如下: 一.Windows+R ...

  9. java后台生成zip打包文件

    /** * * @param zipFile 压缩包文件对象 * @param listKey 压缩的图片物理地址 * @return */ public static boolean package ...

  10. H5 移动Web框架集合

    http://frozenui.github.io/  一个简洁的h5前端框架 http://weui.github.io/weui/ 腾讯出的WebUI 风格是基于微信