poj 1177 矩形并的周长

来源:互联网 发布:少儿编程培训班 编辑:程序博客网 时间:2024/05/19 07:45

可以扫一遍,同时求长和宽的增加段;也可以横纵各扫一遍求边的变化量;

#include<algorithm>#include<iostream>#include<stdio.h>#include<string.h>#include<stdlib.h>#include<vector>#include<queue>#include<cmath>#include<math.h>using namespace std;#define inf 0x3f3f3f3fconst int dir[4][2]={0,1,0,-1,1,0,-1,0};#define maxn 10005struct Tree{int l,r;//左右端点int c;//覆盖情况int cnt,lf,rf;//cnt为长度,lf为实际左坐标,rf为实际右坐标int se;int lc,rc;}tree[maxn*4];struct Line{int x,y1,y2;int f;//直线的标记}line[maxn];bool cmp(Line a,Line b)//sort排序的函数{    return a.x < b.x;}  double y[maxn];//记录y坐标void build(int l,int r,int root){tree[root].l=l;tree[root].r=r;tree[root].c=tree[root].cnt=tree[root].se=0;tree[root].lc=tree[root].rc=0;tree[root].lf=y[l];tree[root].rf=y[r];if(l+1==r)return;int mid=(l+r)>>1;build(l,mid,root<<1);build(mid,r,root<<1|1);}void calen(int root){if(tree[root].c>0){tree[root].cnt=tree[root].rf-tree[root].lf;tree[root].se=1;tree[root].lc=tree[root].rc=1;}else if(tree[root].l+1==tree[root].r) {tree[root].cnt=0;tree[root].se=0;tree[root].lc=tree[root].rc=0;}else {tree[root].cnt=tree[root<<1].cnt+tree[root<<1|1].cnt;tree[root].lc=tree[root<<1].lc;tree[root].rc=tree[root<<1|1].rc;tree[root].se=tree[root<<1].se+tree[root<<1|1].se-tree[root<<1].rc*tree[root<<1|1].lc;}}void update(int root,struct Line e){if(e.y1==tree[root].lf&&e.y2==tree[root].rf){tree[root].c+=e.f;calen(root);return;}if(e.y2<=tree[root<<1].rf)update(root<<1,e);else if(e.y1>=tree[root<<1|1].lf)update(root<<1|1,e);else{Line tmp=e;tmp.y2=tree[root<<1].rf;update(root<<1,tmp);tmp=e;tmp.y1=tree[root<<1|1].lf;update(root<<1|1,tmp);}calen(root);}int main(){int i,j;int n,k,R=0;int x1,y1,x2,y2;while(scanf("%d",&n)!=EOF&&n!=0){R++;k=1;for(i=1;i<=n;i++)        {            scanf("%d%d%d%d",&x1,&y1,&x2,&y2);            line[k].x=x1;            line[k].y1=y1;            line[k].y2=y2;            line[k].f=1;            y[k]=y1;            k++;            line[k].x=x2;            line[k].y1=y1;            line[k].y2=y2;            line[k].f=-1;            y[k]=y2;            k++;        }k--;sort(line+1,line+k+1,cmp);        sort(y+1,y+k+1);int mm;mm=unique(y+1,y+1+k)-y-1;build(1,mm,1);int ans=0,temp=0;for(i=1;i<=k;i++){if(tree[1].cnt!=0)ans+=tree[1].se*(line[i].x-line[i-1].x)*2;update(1,line[i]);ans+=abs(tree[1].cnt-temp);temp=tree[1].cnt;}printf("%d\n",ans);}return 0;}


0 0