求最终的覆盖图形周长,写这种代码应该短而精确,差的比较远
/* 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 ",perimeter); return 0; }