求最终的覆盖图形周长,写这种代码应该短而精确,差的比较远
/* Problem: 1177 User: 96655 Memory: 348K Time: 32MS Language: C++ Result: Accepted */ #include<iostream> #include<stdio.h> #include<stdlib.h> #include<math.h> #include <algorithm> using namespace std; const int maxn=10010; struct Node {int s,t,num,len,cover;bool lb,rb;void change(int o){cover+=o;if(cover==0)len=lb=rb=num=0;else len=t-s,lb=1,rb=1,num=1;} } node[maxn<<2]; struct Line {int x,y1,y2,flag;void fun(int a,int b,int c,int d){x=a,y1=b,y2=c,flag=d;}bool operator<(const Line &e)const{if(x==e.x)return flag>e.flag;return x<e.x;} } line[maxn]; int y[maxn]; void build(int rt,int l,int r) {node[rt].s=y[l];node[rt].t=y[r];node[rt].num=node[rt].len=node[rt].cover=0;if(l+1==r)return;int m=(l+r)>>1;build(rt*2,l,m);build(rt*2+1,m,r); } void update_line(int rt) {node[rt].lb=node[rt*2].lb;node[rt].rb=node[rt*2+1].rb;node[rt].num=node[rt*2].num+node[rt*2+1].num-node[rt*2].rb*node[rt*2+1].lb; } void update_len(int rt) {node[rt].len=node[rt*2].len+node[rt*2+1].len; } void update(int rt,int l,int r,Line e) {if(l+1==r){node[rt].change(e.flag);return;}int m=(l+r)>>1;if(e.y1<node[rt*2].t)update(rt*2,l,m,e);if(e.y2>node[rt*2+1].s)update(rt*2+1,m,r,e);update_len(rt);update_line(rt); } int main() {int n,x1,x2,y1,y2,cnt=0,d=1;scanf("%d",&n);for(int i=1; i<=n; i++){scanf("%d%d%d%d",&x1,&y1,&x2,&y2);line[++cnt].fun(x1,y1,y2,1);y[cnt]=y1;line[++cnt].fun(x2,y1,y2,-1);y[cnt]=y2;}sort(y+1,y+1+cnt);sort(line+1,line+1+cnt);for(int i=2; i<=cnt; ++i)if(y[i]!=y[i-1])y[++d]=y[i];build(1,1,d);int perimeter=0;int now_len=0;int now_num=0;for(int i=1; i<=cnt; ++i){update(1,1,d,line[i]);if(i>1)perimeter+=2*now_num*(line[i].x-line[i-1].x);perimeter+=abs(node[1].len-now_len);now_num=node[1].num;now_len=node[1].len;}printf("%d\n",perimeter);return 0; }