有m个国家(m<=20)对每个国家给定n个城镇 这个国家的围墙是保证围住n个城镇的周长最短的多边形 必然是凸包
进行若干次导弹发射 落到一个国家内则国家被破坏
最后回答总共有多少面积被破坏
首先求凸包
然后判断点是否在凸包内 要用O(logn)的判断方法 不然会超时
这道题常数卡的有点紧 TLE三次才过
蒟蒻没救了 2017年做1991年的题还被卡常数
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
const double eps=1e-9;
int cmp(double x)
{
if(fabs(x)<eps)return 0;
if(x>0)return 1;
else return -1;
}
const double pi=acos(-1.0);
inline double sqr(double x)
{
return x*x;
}
struct point
{
double x,y;
point (){}
point (double a,double b):x(a),y(b){}
void input()
{
scanf("%lf%lf",&x,&y);
}
friend point operator +(const point &a,const point &b)
{
return point(a.x+b.x,a.y+b.y);
}
friend point operator -(const point &a,const point &b)
{
return point(a.x-b.x,a.y-b.y);
}
friend bool operator ==(const point &a,const point &b)
{
return cmp(a.x-b.x)==0&&cmp(a.y-b.y)==0;
}
friend point operator *(const point &a,const double &b)
{
return point(a.x*b,a.y*b);
}
friend point operator*(const double &a,const point &b)
{
return point(a*b.x,a*b.y);
}
friend point operator /(const point &a,const double &b)
{
return point(a.x/b,a.y/b);
}
double norm()
{
return sqrt(sqr(x)+sqr(y));
}
};
struct line
{
point a,b;
line(){};
line(point x,point y):a(x),b(y)
{
}
};
double det(const point &a,const point &b)
{
return a.x*b.y-a.y*b.x;
}
double dot(const point &a,const point &b)
{
return a.x*b.x+a.y*b.y;
}
double dist(const point &a,const point &b)
{
return (a-b).norm();
}
point rotate_point(const point &p,double A)
{
double tx=p.x,ty=p.y;
return point(tx*cos(A)-ty*sin(A),tx*sin(A)+ty*cos(A));
}
bool parallel(line a,line b)
{
return !cmp(det(a.a-a.b,b.a-b.b));
}
bool line_joined(line a,line b,point &res)
{
if(parallel(a,b))return false;
double s1=det(a.a-b.a,b.b-b.a);
double s2=det(a.b-b.a,b.b-b.a);
res=(s1*a.b-s2*a.a)/(s1-s2);
return true;
}
bool pointonSegment(point p,point s,point t)
{
return cmp(det(p-s,t-s))==0&&cmp(dot(p-s,p-t))<=0;
}
void PointProjLine(const point p,const point s,const point t,point &cp)
{
double r=dot((t-s),(p-s))/dot(t-s,t-s);
cp=s+r*(t-s);
}
struct polygon_convex
{
vector<point>P;
polygon_convex(int Size=0)
{
P.resize(Size);
}
};
bool comp_less(const point &a,const point &b)
{
return cmp(a.x-b.x)<0||cmp(a.x-b.x)==0&&cmp(a.y-b.y)<0;
}
polygon_convex convex_hull(vector<point> a)
{
polygon_convex res(2*a.size()+5);
sort(a.begin(),a.end(),comp_less);
a.erase(unique(a.begin(),a.end()),a.end());//删去重复点
int m=0;
for(int i=0;i<a.size();i++)
{
while(m>1&&cmp(det(res.P[m-1]-res.P[m-2],a[i]-res.P[m-2]))<=0)--m;
res.P[m++]=a[i];
}
int k=m;
for(int i=int(a.size())-2;i>=0;--i)
{
while(m>k&&cmp(det(res.P[m-1]-res.P[m-2],a[i]-res.P[m-2]))<=0)--m;
res.P[m++]=a[i];
}
res.P.resize(m);
if(a.size()>1)res.P.resize(m-1);
return res;
}
bool is_convex(vector<point> &a)
{
for(int i=0;i<a.size();i++)
{
int i1=(i+1)%int(a.size());
int i2=(i+2)%int(a.size());
int i3=(i+3)%int(a.size());
if((cmp(det(a[i1]-a[i],a[i2]-a[i1]))*cmp(det(a[i2]-a[i1],a[i3]-a[i2])))<0)
return false;
}
return true;
}
int containO(const polygon_convex &a,const point &b)
{
int n=a.P.size();
point g=(a.P[0]+a.P[n/3]+a.P[2*n/3])/3.0;
int l=0,r=n;
while(l+1<r)
{
int mid=(l+r)/2;
if(cmp(det(a.P[l]-g,a.P[mid]-g))>0)
{
if(cmp(det(a.P[l]-g,b-g))>=0&&cmp(det(a.P[mid]-g,b-g))<0)r=mid;
else l=mid;
}else
{
if(cmp(det(a.P[l]-g,b-g))<0&&cmp(det(a.P[mid]-g,b-g))>=0)l=mid;
else r=mid;
}
}
r%=n;
int z=cmp(det(a.P[r]-b,a.P[l]-b))-1;
if(z==-2)return 1;
return z;
}
polygon_convex pc[30];
double area(int n)
{
double ans=0;
vector<point>a;
a.clear();
for(int i=0;i<pc[n].P.size();i++)
a.push_back(pc[n].P[i]);
a.push_back(a[0]);
for(int i=0;i<a.size()-1;i++)ans+=det(a[i+1],a[i]);
//cout<<ans/2<<endl;
return ans/2.0;
}
int tot;
double are[30];
vector<point> pp;
int shoot[600][600];
bool damed[30];
int main()
{//freopen("t.txt","r",stdin);
int n;
tot=1;
while(scanf("%d",&n)&&n!=-1)
{
pp.clear();
for(int i=0;i<n;i++)
{
point p;
p.input();
pp.push_back(p);
}
pc[tot]=convex_hull(pp);
//cout<<pc[tot].P.size()<<endl;
are[tot]=area(tot);
//cout<<are[tot]<<endl;
tot++;
}
int x,y;
memset(damed,0,sizeof(damed));
int sum=0;
memset(shoot,0,sizeof(shoot));
while(scanf("%d%d",&x,&y)!=EOF)
{
if(sum==tot-1)break;
if(shoot[x][y]==0)
{
for(int i=1;i<tot;i++)
if(containO(pc[i],point(x,y)))
{
shoot[x][y]=i;
break;
}
}
if(!damed[shoot[x][y]]){sum++;damed[shoot[x][y]]=1;}
}
double tarea=0;
for(int i=1;i<tot;i++)
{
//cout<<are[i]<<endl;
if(damed[i])tarea+=are[i];
}
printf("%.2lf\n",-tarea+0.0005);
return 0;
}