题意:

有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. dbutils 执行sql返回的数据类型

    //ArrayHandler: 把结果集中的第一行数据转成对象数组 //ArrayListHandler:把结果集中的每一行数据都转成一个对象数组,再存放到List中 //BeanHandler:将结 ...

  2. c++ 格式化printf

    类型为uint64_t的变量,使用printf进行打印时,需要区分操作系统: 64位系统:使用%ld 32位系统:使用%llu #include<stdio.h>#include < ...

  3. java.lang.UnsatisfiedLinkError: D:\Tomcat-7.0.59\apache-tomcat-7.0.59\bin\tcnative-1.dll: Can't load IA 32-bit .dll on a AMD 64-bit platform

    今日上午用Tomcat运行一个小项目,报出以下异常信息: java.lang.UnsatisfiedLinkError: D:\Tomcat-7.0.59\apache-tomcat-7.0.59\b ...

  4. Java多线程——<四>让线程有返回值

    一.概述 到目前为止,我们已经能够声明并使一个线程任务运行起来了.但是遇到一个问题:现在定义的任务都没有任何返回值,那么加入我们希望一个任务运行结束后告诉我一个结果,该结果表名任务执行成功或失败,此时 ...

  5. hibernate4.0中SessionFactory的创建

    创建SessionFactory 首先创建Configuration对象,主要方式是: new Configuration().configure() 默认情况下Hibernate会去classPat ...

  6. java reflect 例子

    public static void main(String[] args) { Student stu1 = new Student(); stu1.setId(1); stu1.setName(& ...

  7. POJ 3080 Blue Jeans (多个字符串的最长公共序列,暴力比较)

    题意:给出m个字符串,找出其中的最长公共子序列,如果相同长度的有多个,输出按字母排序中的第一个. 思路:数据小,因此枚举第一个字符串的所有子字符串s,再一个个比较,是否为其它字符串的字串.判断是否为字 ...

  8. maven 命令备忘

    1. 打包时 不执行测试 mvn package -Dmaven.test.skip=true

  9. hdu2010

    //很闲,刷水..... http://acm.hdu.edu.cn/showproblem.php?pid=2010 #include<iostream> #include<std ...

  10. java 写文本文件

    code 1:将特定String写入特定文件,不覆盖. import java.io.*; import java.util.*; public class OutputLog { public st ...