题目:
给出n个凸包,现在要用炸弹炸毁固定的坐标,被攻击的坐标所在的凸包会被毁灭,
现在问你被毁灭的凸包的面积
分析:
求凸包+求多边形面积
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> using namespace std; const int X = 105; #define debug puts("here"); int top,n,a[X]; bool use[X]; struct node { int x,y; friend bool operator < (node a,node b) { return a.y<b.y||(a.y==b.y&&a.x<b.x); } }res[X],p[X],in[25][X]; int det(int x1,int y1,int x2,int y2) { return x1*y2-x2*y1; } bool del(int top,int i) { if(det(res[top].x-res[top-1].x,res[top].y-res[top-1].y,p[i].x-res[top].x,p[i].y-res[top].y)<=0) return true; return false; } void graham() { sort(p,p+n); top = 1; res[0] = p[0]; res[1] = p[1]; for(int i=2;i<n;i++) { while(top&&del(top,i)) top--; res[++top] = p[i]; } int mint = top; res[++top] = p[n-2]; for(int i=n-3;i>=0;i--) { while(top!=mint&&del(top,i)) --top; res[++top] = p[i]; } } int det(node a,node b,node o) { return (a.x-o.x)*(b.y-o.y)-(a.y-o.y)*(b.x-o.x); } bool check(node cur,int id) { for(int i=0;i<a[id]-1;i++) if(det(in[id][i],in[id][i+1],cur)*det(in[id][i+1],in[id][i+2],cur)<0) return false; return true; } double dis(node a,node b) { return sqrt((a.x-b.x)*1.0*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); } double cal(int id) { double ans = 0; for(int i=1;i<a[id];i++) ans += det(in[id][i],in[id][i+1],in[id][0]); ans /= 2; ans = max(ans,-ans); return ans; } double solve(int x,int y,int cnt) { node cur; cur.x = x; cur.y = y; for(int i=1;i<=cnt;i++) if(!use[i]&&check(cur,i)) { use[i] = true; return cal(i); } return 0; } int main() { memset(use,false,sizeof(use)); int cnt = 0; while(cin>>n,n!=-1) { for(int i=0;i<n;i++) scanf("%d%d",&p[i].x,&p[i].y); graham(); cnt++; for(int i=0;i<=top;i++) in[cnt][i] = res[i]; a[cnt] = top; } int x,y; double ans = 0; while(cin>>x>>y) ans += solve(x,y,cnt); printf("%.2lf\n",ans); return 0; }