hdu1542 && pku 1151 Atlantis(面积并)
求N个矩形的面积并,这个比周长并要简单的多,不过涉及到了离散化,根据相对大小,给对应的double型数据编号,插入是再二分查找编号即可
也可以用矩形切割去做,代码简单很多
矩形切割
#include<iostream> #include<algorithm> #include<string> #include<math.h> using namespace std; const int N = 100+10; struct rec { double p1[2],p2[2]; }r[N]; rec rr[N*N]; int total; inline double get_area(rec& a) { return (a.p2[0]-a.p1[0])*(a.p2[1]-a.p1[1]); } inline bool cut_rec(rec &now,rec t)//矩形切割 { for(int i=0;i<2;i++) if(t.p1[i]>=now.p2[i] || t.p2[i]<=now.p1[i]) return false; rec tmp; double k1,k2; for(int i=0;i<2;i++) { k1=max(t.p1[i],now.p1[i]); k2=min(t.p2[i],now.p2[i]); if(t.p1[i]<k1) { tmp=t; tmp.p2[i]=k1; rr[total++]=tmp; } if(t.p2[i]>k2) { tmp=t; tmp.p1[i]=k2; rr[total++]=tmp; } t.p1[i]=k1; t.p2[i]=k2; } return true; } int main() { int n,cas=0; while(scanf("%d",&n)==1 && n) { for(int i=0;i<n;i++) scanf("%lf %lf %lf %lf",&r[i].p1[0],&r[i].p1[1],&r[i].p2[0],&r[i].p2[1]); total=0; for(int i=0;i<n;i++) { for(int j=0;j<total;j++) { if(cut_rec(r[i],rr[j])) { rr[j]=rr[total-1]; total--; j--; } } rr[total++]=r[i]; } double ans=0; for(int i=0;i<total;i++) ans+=get_area(rr[i]); printf("Test case #%d\n",++cas); printf("Total explored area: %.2f\n\n",ans); } return 0; }
#include<iostream> #include<algorithm> #include<map> #define maxn 222 using namespace std; struct node { double x,y1,y2; int s; node(double a=0,double b=0,double c=0,int d=0):x(a),y1(b),y2(c),s(d){} friend bool operator<(const node a,const node b) { return a.x<b.x; } }; node ss[maxn]; bool cmp(node a,node b) { return a.x<b.x; } double len[maxn<<2]; int cnt[maxn<<2]; double map1[maxn]; void PushUp(int k,int s,int t) { if(cnt[k]) len[k]=map1[t+1]-map1[s]; else if(t==s) len[k]=0; else len[k]=len[k<<1]+len[k<<1 |1]; } void update(int l,int r,int c,int s,int t,int k) { if(l<=s && t<=r) { cnt[k]+=c; PushUp(k,s,t); return ; } int kl=k<<1,kr=kl+1,mid=(s+t)>>1; if(l<=mid) update(l,r,c,s,mid,kl); if(r>mid) update(l,r,c,mid+1,t,kr); PushUp(k,s,t); } int Bin(double key,int n,double map1[]) { int l = 0 , r = n - 1; while (l <= r) { int mid = (l + r) >> 1; if (map1[mid] == key) return mid; if (map1[mid] < key) l = mid + 1; else r = mid - 1; } return -1; } int main() { double a,b,c,d; int n,cas=0; while(scanf("%d",&n)==1 &&n) { int m=0; for(int i=0;i<n;i++) { scanf("%lf %lf %lf %lf",&a,&b,&c,&d); map1[m]=b; ss[m++]=node(a,b,d,1); map1[m]=d; ss[m++]=node(c,b,d,-1); } sort(map1,map1+m); sort(ss,ss+m); int k=1; for (int i = 1 ; i < m ; i ++) if (map1[i] != map1[i-1]) map1[k++] =map1[i]; memset(cnt , 0 , sizeof(cnt)); memset(len , 0 , sizeof(len)); double ans=0; for(int i=0;i<m-1;i++) { int l = Bin(ss[i].y1 , k , map1); int r = Bin(ss[i].y2 , k , map1) - 1; if (l <= r) update(l , r , ss[i].s , 0 , k - 1, 1); ans+=len[1]*(ss[i+1].x-ss[i].x); } printf("Test case #%d\nTotal explored area: %.2lf\n\n",++cas,ans); } return 0; }