poj1177 Picture 离散 注意排序

xiaoxiao2021-02-28  150

参考 http://www.cnblogs.com/kuangbin/archive/2013/04/10/3013437.html

但他是错的

3 0 0 1 2 0 2 1 4 1 1 2 3 12 3 0 1 2 2 2 1 4 2 1 0 3 1 12 如上这两组数据

/*

POJ 1177 矩形周长并,求轮廓周长 这题可以不离散化做的,我做的是离散化以后的 这题和矩形面积并有类似的地方 把矩形变成一条条平行于x轴的线段(当然弄成平行于y轴的也是可以的) 要累加的一个是覆盖的线段长度的变化,还有就是竖直的线段。 离散化以后一定要进行去掉重复的点,因为会影响后面合并的时候。 STL中的unique()函数可以快速去掉相同元素 */ #include <stdio.h> #include <iostream> #include <string.h> #include <algorithm> using namespace std; const int MAXN=10010; struct Node {     int l,r;     int cnt;//有效长度     int lf,rf;//实际的左右端点     int numseg;//分支数,一个分支对应两条竖线     int c;//记录覆盖情况     bool lcover,rcover; }segTree[MAXN*4]; struct Line {     int y1,y2;     int x;     int f;     Line(): x(0), y1(0), y2(0), f(0){}     Line(int a, int b, int c, int d): x(a), y1(b), y2(c), f(d){} }line[MAXN]; bool cmp(Line a,Line b) {     if(a.x==b.x)         return a.f>b.f; //这句非常重要不写会错  return a.x<b.x; } int y[MAXN]; void Build(int i,int l,int r) {     segTree[i].l=l;     segTree[i].r=r;     segTree[i].lf=y[l];     segTree[i].rf=y[r];     segTree[i].cnt=0;     segTree[i].numseg=0;     segTree[i].c=0;     segTree[i].lcover=segTree[i].rcover=false;     if(l+1==r)return;     int mid=(l+r)/2;     Build(i<<1,l,mid);     Build((i<<1)|1,mid,r); } void calen(int i) {     if(segTree[i].c>0)     {         segTree[i].cnt=segTree[i].rf-segTree[i].lf;         segTree[i].numseg=1;         segTree[i].lcover=segTree[i].rcover=true;         return;     }     if(segTree[i].l+1==segTree[i].r)     {         segTree[i].cnt=0;         segTree[i].numseg=0;         segTree[i].lcover=segTree[i].rcover=false;     }     else     {         segTree[i].cnt=segTree[i<<1].cnt+segTree[(i<<1)|1].cnt;         segTree[i].lcover=segTree[i<<1].lcover;         segTree[i].rcover=segTree[(i<<1)|1].rcover;         segTree[i].numseg=segTree[i<<1].numseg+segTree[(i<<1)|1].numseg;         if(segTree[i<<1].rcover&&segTree[(i<<1)|1].lcover)segTree[i].numseg--;     } } void update(int i,Line e) {     if(segTree[i].lf==e.y1&&segTree[i].rf==e.y2)     {         segTree[i].c+=e.f;         calen(i);         return;     }          if(e.y2<=segTree[i<<1].rf) update(i<<1,e);     else if(e.y1>=segTree[(i<<1)|1].lf) update((i<<1)|1,e);     else     {         Line temp=e;         temp.y2=segTree[i<<1].rf;         update(i<<1,temp);         temp=e;         temp.y1=segTree[(i<<1)|1].lf;         update((i<<1)|1,temp);     }     calen(i); } int main() {     int x1,y1,x2,y2;     int n;     while(scanf("%d",&n)==1)     {         int t=0;         for(int i=0;i<n;i++)         {             scanf("%d%d%d%d",&x1,&y1,&x2,&y2);             line[t]=Line(x1, y1, y2, 1); y[t++]=y1;             line[t]=Line(x2, y1, y2, -1);             y[t++]=y2;         }         sort(line,line+t,cmp);         sort(y,y+t);         int m=unique(y,y+t)-y;//合并相同元素,这里一点要合并相同元素,否则会WA.          Build(1,0,m-1);         //Build(1,0,t-1);         int ans=0;         int last=0; int lines=0;         for(int i=0;i<t-1;i++)         {             update(1,line[i]);             ans+=segTree[1].numseg*2*(line[i+1].x-line[i].x);             ans+=abs(segTree[1].cnt-last);             last=segTree[1].cnt;         }         update(1,line[t-1]);         ans+=abs(segTree[1].cnt-last);         printf("%d\n",ans);     }     return 0; }
转载请注明原文地址: https://www.6miu.com/read-19089.html

最新回复(0)