啦啦啦~继续学算法
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1542
2 10 10 20 20 15 15 25 25.5 0
Test case #1 Total explored area: 180.00参考自:http://blog.csdn.net/kk303/article/details/9493265(1)注意double~ (2)用二分解决离散化的问题#include <iostream> #include <string> #include <string.h> #include <cstdio> #include <algorithm> const int N=220; const double eps=1e-6; using namespace std; struct node { double x1,x2,y; int tp; }line[N*4]; bool cmp(node a,node b) { return a.y-b.y<eps; //或者写成这样 return a.y-b.y<eps 有精度问题 } int n,times[N*4]; double sum[N*4]; //隐式构建线段树 double xx[N*4]; int find(double x) { int l=1,r=n; while(l<=r) { int mid=(l+r)/2; if(xx[mid]==x)return mid; else if(xx[mid]<x)l=mid+1; else r=mid; } return l; } void update(int x,int t,int l,int r,int v) { if(l==r) { times[x]+=t; if(times[x])sum[v]=xx[x+1]-xx[x]; else sum[v]=0; return; } int mid=(l+r)/2; if(x<=mid)update(x,t,l,mid,2*v); else update(x,t,mid+1,r,2*v+1); sum[v]=sum[2*v]+sum[2*v+1]; } int main() { int test=1; while(scanf("%d",&n)!=EOF) { if(n==0)break; memset(sum,0,sizeof(sum)); memset(times,0,sizeof(times)); memset(xx,0,sizeof(xx)); int num=0; for(int i=1;i<=n;i++) { double x1,y1,x2,y2; scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); line[++num].x1=x1; line[num].x2=x2; line[num].y=y1; line[num].tp=1; xx[num]=x1; line[++num].x1=x1; line[num].x2=x2; line[num].y=y2; line[num].tp=-1; xx[num]=x2; } n=n*2; sort(xx+1,xx+1+num); sort(line+1,line+1+num,cmp); double ans=0.0; for(int i=1;i<=num;i++) { ans+=sum[1]*(line[i].y-line[i-1].y); int l=find(line[i].x1); int r=find(line[i].x2)-1; for(int j=l;j<=r;j++)update(j,line[i].tp,1,n,1); } printf("Test case #%d\n",test++); printf("Total explored area: %.2lf\n",ans); printf("\n"); } return 0; }
原文地址:http://blog.csdn.net/liusuangeng/article/details/40789297