rt,WA on #8#10,应该是算大了,找了一天了没找到问题所在qwq
恳请各位路过的大佬能甩给蒟蒻一个hack,或者帮忙看看程序/kk
悬赏关注qwq万分感谢
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstdio>
using namespace std;
#define EPS 1e-5
#define MAXN 5005
struct point{
double x,y;
point operator-(point k) const{
return {x-k.x,y-k.y};
}
}tb[MAXN],km[MAXN];
struct line{
point a,b;
}a[MAXN],p[MAXN];
int n,s[MAXN],l,r,cnt,ktb;
double cross(point x,point y){
return x.x*y.y-x.y*y.x;
}
double polar(point k){
return atan2(k.y,k.x);
}
bool cmp(line x,line y){
double ax=polar(x.b-x.a),ay=polar(y.b-y.a);
if(abs(ax-ay)<=EPS) return cross(x.b-x.a,y.b-x.a)>=0;
return ax<ay;
}
void rotate(point &k,double alpha){
point tmp;
double sina=sin(alpha),cosa=cos(alpha);
tmp.x=cosa*k.x-sina*k.y;
tmp.y=sina*k.x+cosa*k.y;
k=tmp;
}
point getmix(line x,line y){
point a=x.a,b=x.b,c=y.a,d=y.b;
point k1=a;
b=b-a,c=c-a,d=d-a;
double alpha=atan2(b.y,b.x);
rotate(b,-alpha);
rotate(c,-alpha);
rotate(d,-alpha);
point p;
p.x=(c.x*d.y-c.y*d.x)/(d.y-c.y);
p.y=0;
rotate(p,alpha);
p={p.x+k1.x,p.y+k1.y};
return p;
}
bool onright(line x,line p1,line p2){
point kp=getmix(p1,p2);
return cross(x.b-x.a,kp-x.a)<0;
}
int main(){
int kn,m;
cin>>kn;
while(kn--){
cin>>m;
for(int i=1;i<=m;i++) cin>>km[i].x>>km[i].y;
for(int i=1;i<m;i++) a[++n]={km[i],km[i+1]};
a[++n]={km[m],km[1]};
}
sort(a+1,a+1+n,cmp);//排序,已经处理好平行情况
l=1;
for(int i=1;i<n;i++){//去掉平行线,留最左边的
if(abs(polar(a[i].b-a[i].a)-polar(a[i+1].b-a[i+1].a))<=EPS) continue;
p[++cnt]=a[i];
}
p[++cnt]=a[n];
for(int i=1;i<=cnt;i++){//找到围成凸包的线
if(r>l&&(abs(polar(p[s[r]].b-p[s[r]].a)-polar(p[s[r-1]].a-p[s[r-1]].b))<=EPS
||abs(polar(p[s[l]].b-p[s[l]].a)-polar(p[s[l+1]].a-p[s[l+1]].b))<=EPS)){
printf("0.000");
return 0;
}
while(r>l&&onright(p[i],p[s[r-1]],p[s[r]])) r--;
while(r>l&&onright(p[i],p[s[l]],p[s[l+1]])) l++;
s[++r]=i;
}
while(r>l&&onright(p[s[l]],p[s[r-1]],p[s[r]])) r--;
while(r>l&&onright(p[s[r]],p[s[l]],p[s[l+1]])) l++;
for(int i=l;i<r;i++){//用线求凸包
// cout<<p[s[i]].a.x<<" "<<p[s[i]].a.y<<";"<<p[s[i]].b.x<<" "<<p[s[i]].b.y<<" ; ";
// cout<<p[s[i+1]].a.x<<" "<<p[s[i+1]].a.y<<";"<<p[s[i+1]].b.x<<" "<<p[s[i+1]].b.y<<endl;
tb[++ktb]=getmix(p[s[i]],p[s[i+1]]);
}
tb[++ktb]=getmix(p[s[r]],p[s[l]]);
tb[++ktb]=tb[1];
double ans=0;
for(int i=1;i<ktb;i++){//三角剖分求面积
ans+=cross(tb[i],tb[i+1]);
}
ans=abs(ans/2);
printf("%.3lf",ans);
return 0;
}