蒟蒻80分求助!求hack!悬赏关注
查看原帖
蒟蒻80分求助!求hack!悬赏关注
166234
Aiopr_2378楼主2022/12/12 21:18

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;
}
2022/12/12 21:18
加载中...