bzoj1378: [Baltic2002]Tri

本文介绍了一种使用扫描线算法解决特定几何问题的方法。通过优化处理,确保了算法效率,并分享了一个具体的实现案例。作者还讨论了如何通过排序来简化问题,并提出希望得到关于扫描线根数复杂度的进一步证明。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

传送门
这种水题咋没人做?
大力扫描线一发就可以辣。
小优化:先将三角形按照左下角的x坐标排序
这样在之后做扫描线是左端点保证单调递增。
单词扫描线O(N)就够了。
然后一不小心就Rk1辣?
如果有神犇会证明不同扫描线根数为O(N)级别的请私信我。
挖坑。

#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 2005000
using namespace std;
struct tri{int x,y,m;}a[2005];
int b[N],c[N],e[N];
int n,m,l,r,d,cnt,ans;
bool cmp(tri x,tri y){
    return x.x<y.x;
}
int main(){
    scanf("%d",&n);
    for (int i=1;i<=n;i++){
        scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].m);
        b[++cnt]=a[i].y;
        b[++cnt]=a[i].y+a[i].m;
    }
    for (int i=1;i<=n;i++)
        for (int j=1;j<=n;j++)
            if (i!=j)
                if (a[i].x<=a[j].x&&a[i].x+a[i].m>=a[j].x){
                    int y=a[i].y+(a[i].x+a[i].m-a[j].x);
                    if (y>=a[j].y&&y<=a[j].y+a[j].m) b[++cnt]=y;
                }
    sort(b+1,b+cnt+1);
    sort(a+1,a+n+1,cmp);
    m=1;
    for (int i=2;i<=cnt;i++)
        if (b[i]!=b[i-1])
            b[++m]=b[i];
    for (int i=1;i<=m;i++){
        l=r=-1e9;
        for (int j=1;j<=n;j++){
            d=a[j].m-(b[i]-a[j].y);
            if (d<0||d>a[j].m) continue;
            if (a[j].x>r){
                c[i]+=r-l;
                r=a[j].x+d;
                l=a[j].x;
            }
            else if (a[j].x+d>r)
                r=a[j].x+d;
        }
        c[i]+=r-l;
        l=r=-1e9;
        for (int j=1;j<=n;j++){
            d=a[j].m-(b[i]-a[j].y);
            if (d<0||d>=a[j].m) continue;
            if (a[j].x>r){
                e[i]+=r-l;
                r=a[j].x+d;
                l=a[j].x;
            }
            else if (a[j].x+d>r)
                r=a[j].x+d;
        }
        e[i]+=r-l;
    }
    for (int i=1;i<m;i++)
        ans+=(b[i+1]-b[i])*(c[i]+e[i+1]);
    printf("%d.%d",ans/2,(ans&1)?5:0);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值