题意:给你n个矩阵求覆盖面积。
思路:看了别人的结题报告
给定一个矩形的左下角坐标和右上角坐标分别为:(x1,y1)、(x2,y2),对这样的一个矩形,我们构造两条线段,一条定位在x1,它在y坐标的区间是[y1,y2],并且给定一个cover域值为1;另一条线段定位在x2,区间一样是[y1,y2],给定它一个cover值为-1。根据这样的方法对每个矩形都构造两个线段,最后将所有的线段根据所定位的x从左到右进行排序
#include <iostream> #include <stdio.h> #include <string.h> #include <algorithm> using namespace std; #define M 100 #define inf 0x3fffffff #define maxn 500000*2 struct seg { int flag; double up,down,x; }line[M*5]; int cmp(seg a,seg b) { return a.x<b.x; } struct Tree { double up,down,x; int cover; bool flag; }tree[M*M]; double y[M*3];//对y进行分割,建树 void build(int id,int l,int r) { tree[id].down=y[l];tree[id].up=y[r]; tree[id].flag=false;tree[id].cover=0;tree[id].x=-1; if(l+1==r) { tree[id].flag=true; return ; } int mid=(l+r)/2; build(id*2,l,mid); build(id*2+1,mid,r); } double insert(int id,double x,double l,double r,int flag)//flag表示为左边还是右边 { if(tree[id].down>=r||tree[id].up<=l) return 0; if(tree[id].flag) { if(tree[id].cover>0)//递归到了叶子节点 { double temp_x=tree[id].x; double ans=(x-temp_x)*(tree[id].up-tree[id].down); tree[id].x=x;//定位上一次的x tree[id].cover+=flag; return ans; } else { tree[id].cover+=flag; tree[id].x=x; return 0; } } double ans1,ans2; ans1=insert(id*2,x,l,r,flag); ans2=insert(id*2+1,x,l,r,flag); return ans1+ans2; } int main() { int t,ca=1; while(scanf("%d",&t)&&t) { double x1,x2,y1,y2; int k=0; for(int i=0;i<t;i++) { scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); k++; y[k]=y1; line[k].down=y1; line[k].up=y2; line[k].x=x1; line[k].flag=1;//1表示左边 k++; y[k]=y2; line[k].x=x2; line[k].down=y1; line[k].up=y2; line[k].flag=-1;//-1表示右边 } sort(y+1,y+k+1); sort(line+1,line+1+k,cmp); build(1,1,k); double ans=0; for(int i=1;i<=k;i++) ans+=insert(1,line[i].x,line[i].down,line[i].up,line[i].flag); printf("Test case #%d\nTotal explored area: %.2f\n\n",ca++,ans); } return 0; } /* 2 10 10 20 20 15 15 25 25.5 0 */
HDU 1542 Atlantis (线段树求矩阵覆盖面积)
时间: 2024-10-09 18:03:35