UVA1475 Jungle Outpost(半平面交)

原题链接:UVA1475

分析:首先要知道这个结论:敌人最优的炸法是连续轰炸,而不是分散火力。
我发现网上大多数博客都没有证明这个结论,来给大家一个简单的证明好了:
如图所示,我们先轰炸A点得到三角形AEF,接下来如果轰炸B点得到三角形BEF,如果轰炸C点得到三角形BCD
那么现在问题转化为证明BEF的面积大于BCD的面积。

因为B与E隔F,A两个点,而B与D之隔只有点C,所以BE会倾向于大于BD,同理高h1也会倾向于大于h2,

所以在这个六边形上枚举两个相邻的点轰炸必定最优,在n条边多边形连续轰炸m个点也会比分散轰炸更优,证完了。。。

有了这个结论问题就简单多了,我们只要结合半平面交二分答案就好了,下面是AC代码:

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 typedef long long ll;
  4 double eps=1e-15;
  5 double pi=acos(-1);
  6 struct Point{
  7     double x,y;
  8     Point(double x=0,double y=0):x(x),y(y){}
  9 };
 10 typedef Point Vector;
 11 Vector operator + (Vector A,Vector B){return Vector(A.x+B.x,A.y+B.y);}
 12 Vector operator - (Vector A,Vector B){return Vector(A.x-B.x,A.y-B.y);}
 13 Vector operator * (Vector A,double B){return Vector(A.x*B,A.y*B);}
 14 Vector operator / (Vector A,double B){return Vector(A.x/B,A.y/B);}
 15 int dcmp(double x){
 16     if(fabs(x)<eps)return 0;
 17     else return x<0?-1:1;
 18 }
 19 bool operator < (const Point &a,const Point &b){
 20     return dcmp(a.x-b.x)<0||(dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)<0);
 21 }
 22 bool operator == (const Point &a,const Point &b){
 23     return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0;
 24 }
 25 double Cross(Vector A,Vector B){
 26     return A.x*B.y-A.y*B.x;
 27 }
 28 double Dot(Vector A,Vector B){
 29     return A.x*B.x+A.y*B.y;
 30 }
 31 int dis(Point A,Point B){
 32     return (A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y*B.y);
 33 }
 34 Vector Rotate(Vector A,double rad){
 35     return Vector(A.x*cos(rad)-A.y*sin(rad),A.x*sin(rad)+A.y*cos(rad));
 36 }
 37 double len(Vector v)
 38 {
 39     return sqrt(Dot(v,v));
 40 }
 41 Vector normal(Vector v)
 42 {
 43     Vector u=(Vector){-v.y,v.x};
 44     return u/len(u);
 45 }
 46 void readp(Point &A){
 47     scanf("%lf%lf",&A.x,&A.y);
 48 }
 49 struct Line{
 50     Point p;
 51     Vector v;
 52     double ang;
 53     Line(){}
 54     Line(Point p,Vector v):p(p),v(v){ang=atan2(v.y,v.x);}
 55     bool operator < (const Line& L)const {
 56         return ang<L.ang;
 57     }
 58 };
 59 bool onleft(Line L,Point p){
 60     return Cross(L.v,p-L.p)>0;
 61 }
 62 Point getintersection(Line a,Line b){
 63     Vector u=a.p-b.p;
 64     double t=Cross(b.v,u)/Cross(a.v,b.v);
 65     return a.p+a.v*t;
 66 }
 67 int bpmj(Line *L,int n,Point *poly){
 68     sort(L,L+n);
 69     int first,last;
 70     Point *p=new Point[n];
 71     Line *q=new Line[n];
 72     q[first=last=0]=L[0];
 73     for(int i=1;i<n;i++){
 74         while(first<last&&!onleft(L[i],p[last-1]))last--;
 75         while(first<last&&!onleft(L[i],p[first]))first++;
 76         q[++last]=L[i];
 77         if(fabs(Cross(q[last].v,q[last-1].v))<eps){
 78             last--;
 79             if(onleft(q[last],L[i].p))q[last]=L[i];
 80         }
 81         if(first<last)p[last-1]=getintersection(q[last-1],q[last]);
 82     }
 83     while(first<last&&!onleft(q[first],p[last-1]))last--;
 84     if(last-first<=1)return 0;
 85     p[last]=getintersection(q[last],q[first]);
 86     int m=0;
 87     for(int i=first;i<=last;i++)poly[m++]=p[i];
 88     return m;
 89 }
 90 int n;
 91 const int maxn=50005;
 92 Point p[maxn],poly[maxn];
 93 Line L[maxn];
 94 int main(){
 95     while(~scanf("%d",&n)){
 96         for(int i=0;i<n;i++){
 97             readp(p[i]);
 98         }
 99         int l=1,r=n+1;
100         while(l<r){
101             int m=(l+r)/2;
102             int cnt=0;
103             for(int i=0;i<n;i++){
104                 int j=(i+m+1)%n;
105                 Vector v=p[i]-p[j];
106                 L[cnt++]=Line(p[i],v);
107             }
108             if(!bpmj(L,cnt,poly))r=m;
109             else l=m+1;
110         }
111         printf("%d\n",l);
112     }
113 }

 

转载于:https://www.cnblogs.com/ccsu-kid/p/9523385.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值