hdu3265一种错误的做法

Posted MalcolmMeng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu3265一种错误的做法相关的知识,希望对你有一定的参考价值。

题目链接

这是求面积并的题目,刚开始我的思路是将挖去的矩形的入边和出边覆盖效果颠倒,

即入边-1,出边+1,后来调试到爆炸,发现这是错误的做法。。原因就是对最简单

的面积并问题没有搞清楚。刚开始接触扫描线的时候我就有一个问题,为什么覆盖

次数不需要向子区间传递,但是我没有仔细去想这个问题,直到遇到这道题目。在

求相交矩形面积并的过程中,所有的线段都是成对出现,重点在于所有线段的覆盖

都是整段整段的操作,所以不需要向下传。而这道题目用这种做法就会出现一个区

间被较小的区间释放的情况,所以会出错。

技术分享图片
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=310;//最多矩形个数
struct edge{
    int x1,x2,y;
    int f;//1表示入,-1表示出
    edge(){}
    edge(int _x1,int _x2,int _y,int _f){
        x1=_x1,x2=_x2,y=_y,f=_f;
    }
    bool operator <(edge &e){
        if(y!=e.y)
            return y<e.y;
        return f>e.f;
    }
};
int nVx;
int Vx[maxn*4];
int nSgs;
edge Sgs[maxn*4];
int num[maxn*4*4];
int len[maxn*4*4];
void build(int root,int l,int r)
{
    num[root]=len[root]=0;
    if(l==r)return;
    int mid=(l+r)/2;
    build(root*2,l,mid);
    build(root*2+1,mid+1,r);
}
void pushUp(int root,int l,int r)
{
    if(num[root]!=0)len[root]=Vx[r+1]-Vx[l];
    else if(l==r)len[root]=0;
    else len[root]=len[root*2]+len[root*2+1];
    printf("%d %d num[%d]=%d\n",l,r,root,num[root]);
}
void update(int root,int L,int R,int f,int l,int r)
{
    //printf("%d %d %d %d %d %d\n",root,L,R,f,l,r);
    if(L<=l&&r<=R){
        num[root]+=f;
        pushUp(root,l,r);
        return ;
    }
    int mid=(l+r)/2;
    if(L<=mid)update(root*2,L,R,f,l,mid);
    if(mid<R)update(root*2+1,L,R,f,mid+1,r);
    pushUp(root,l,r);
}
int bin(int k)
{
    int l=0,r=nVx-1,mid;
    while(l<=r){
        mid=(l+r)/2;
        if(Vx[mid]==k)return mid;
        else if(Vx[mid]>k)r=mid-1;
        else l=mid+1;
    }
    return -1;
}
int myUnique(int a[],int n)
{
    int sz=1;
    for(int i=1;i<n;i++){
        if(a[i]!=a[i-1])a[sz++]=a[i];
    }
    return sz;
}
int main()
{
    freopen("in.txt","r",stdin);
    int N;
    while(scanf("%d",&N)!=EOF&&N!=0){
        nVx=0;
        nSgs=0;
        for(int i=0;i<N;i++){
            int x1,y1,x2,y2,x3,y3,x4,y4;
            scanf("%d%d%d%d%d%d%d%d",
                &x1,&y1,&x2,&y2,&x3,&y3,&x4,&y4);
            printf("%d %d %d %d %d %d %d %d\n",
                x1,y1,x2,y2,x3,y3,x4,y4);
            Vx[nVx++]=x1,Vx[nVx++]=x2,Vx[nVx++]=x3,Vx[nVx++]=x4;
            Sgs[nSgs++]=edge(x1,x2,y1,1);
            Sgs[nSgs++]=edge(x1,x2,y2,-1);
            Sgs[nSgs++]=edge(x3,x4,y3,-1);
            Sgs[nSgs++]=edge(x3,x4,y4,1);
        }
        sort(Vx,Vx+nVx);
        nVx=myUnique(Vx,nVx);
        sort(Sgs,Sgs+nSgs);
        build(1,0,nVx-1);
        int area=0;
        for(int i=0;i<nSgs-1;i++){
            int l=bin(Sgs[i].x1);
            int r=bin(Sgs[i].x2)-1;
            update(1,l,r,Sgs[i].f,0,nVx-1);
            printf("%d %d\n",len[1],Sgs[i+1].y-Sgs[i].y);
            area+=len[1]*(Sgs[i+1].y-Sgs[i].y);
        }
        printf("%d\n",area);
    }
    while(1);
}
View Code

 先贴一下思路:海报一张可以切割成4个矩形,然后就是普通的矩形面积并了,利

用线段树维护即可

以上是关于hdu3265一种错误的做法的主要内容,如果未能解决你的问题,请参考以下文章

HDU3265 线段树(扫描线)

querydefs 运行时错误 3265:在此集合中找不到项目

使用单个片段显示UI而不是活动是一种好习惯吗?

Computer HDU - 2196

hdu1814 Peaceful Commission

HDU - 1427 / UESTC - 1252 经典dfs