半平面交 — 模板
半平面交
题目描述
#include<map> #include<cmath> #include<queue> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define inf 1000000007 #define ll long long #define N 1510 #define db double inline int rd() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } struct mp{db x,y;}a[N],g[N]; mp operator +(mp a,mp b){return (mp){a.x+b.x,a.y+b.y};} mp operator -(mp a,mp b){return (mp){a.x-b.x,a.y-b.y};} db operator *(mp a,mp b){return a.x*b.y-b.x*a.y;} mp operator *(db a,mp b){return (mp){b.x*a,b.y*a};} struct xx{mp x,y;db af;}b[N],f[N]; bool operator <(xx a,xx b){return a.af==b.af?a.y*(b.x-a.x)<0:a.af<b.af;} int T,n; bool fl; mp Q(xx a,xx b) { db t=a.y*b.y; if(!t){puts("0.00");fl=1;} return (b.y*(a.x-b.x))/t*a.y+a.x; } void sol() { fl=0;n=rd(); for(int i=1;i<=n;i++){a[i].x=rd();a[i].y=rd();} reverse(a+1,a+n+1); a[n+1]=a[1]; for(int i=1;i<=n;i++) b[i]=(xx){a[i],a[i+1]-a[i],atan2((a[i+1]-a[i]).y,(a[i+1]-a[i]).x)}; sort(b+1,b+n+1); int l=1,r=0; for(int i=1;i<=n;i++) { if(i==1||b[i].af>b[i-1].af) { xx x=b[i]; while(l<r&&x.y*(g[r]-x.x)<=0) r--; while(l<r&&x.y*(g[l+1]-x.x)<=0) l++; f[++r]=x; if(l<r) g[r]=Q(f[r-1],x); if(fl) return; } } g[l]=g[r+1]=Q(f[l],f[r]); if(fl) return; db ans=0; for(int i=l;i<=r;i++) ans+=g[i]*g[i+1]; printf("%.2lf\n",abs(ans)*1.0/2); } int main() { T=rd(); while(T--) sol(); return 0; } /* 1 7 0 0 4 4 4 7 9 7 13 -1 8 -6 4 -4 */
发表评论