There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. Some of these texts even include maps of parts of the island. But unfortunately, these maps describe different regions of Atlantis. Your friend Bill has to know the total area for which maps exist. You (unwisely) volunteered to write a program that calculates this quantity.
Input
The input file consists of several test cases. Each test case starts with a line containing a single integer n (1<=n<=100) of available maps. The n following lines describe one map each. Each of these lines contains four numbers x1;y1;x2;y2 (0<=x1
The input file is terminated by a line containing a single 0. Don’t process it.
Output
For each test case, your program should output one section. The first line of each section must be “Test case #k”, where k is the number of the test case (starting with 1). The second one must be “Total explored area: a”, where a is the total explored area (i.e. the area of the union of all rectangles in this test case), printed exact to two digits to the right of the decimal point.
Output a blank line after each test case.
Sample Input
2
10 10 20 20
15 15 25 25.5
0
Sample Output
Test case #1
Total explored area: 180.00
题意:给出n个矩形的左上角和右下角的坐标,计算多个矩形重叠后的面积
思路:线段树+离散化+扫描线
1.直接离散化因为矩形数量只有最多100个,所以朴素O(n*n*n)也是可以的,判断小矩形是不是在大矩形内
假设输入的矩阵中共有num1个不同的x坐标和num2个不同的y坐标,那么整个二维平面就被分割成了(num1-1)*(num2-1)个小方格矩形. 我们只要看上面(num1-1)*(num2-1)个小方格矩形哪些被某个大矩形覆盖,哪些没有被任何一个大矩形覆盖即可.我们令mp[i][j]=1表示以(x[i], y[j])点为左上角,以(x[i+1], y[j+1])点为右上角的那个小矩形被某个大矩形覆盖了. 假设大矩形a[i]的x坐标范围在[xi,xj]之间而y坐标在[yk,yh]之间.那么该大矩阵I肯定使得 所有的mp[a][b]==1. 其中i<=a
#include
#include
#include
using namespace std;
const int maxn=200+5;
struct Node//矩形
{
double x1,y1,x2,y2;
}nodes[maxn];
double x[maxn],y[maxn];
bool mp[maxn][maxn];
int find(double *x,double val,int n)//在数组x中找到val值的位置
{
int L=0,R=n-1;
while(R>=L)
{
int mid=L+(R-L)/2;
if(x[mid]==val) return mid;
else if(x[mid]>val) R=mid-1;
else L=mid+1;
}
return -1;
}
int main()
{
int n,num1,num2,kase=0;
while(scanf("%d",&n)==1 && n)
{
num1=num2=0;//num1记录有多少个不同x值,num2记录y的
memset(mp,0,sizeof(mp));
for(int i=0;i
2.线段树+离散化+扫描线(好难理解QAQ)时间复杂度O(n*logn)
扫描线
对一个四元组(x,y1.y2,k) 在[y1,y2-1]这个区间上执行修改,该区间的线段树
被划分为O(logN)个节点,每个节点的cnt+k
对于线段树中任意一个节点[l,r] 若cnt>0 则len等于a[rt].rf-a[rt].lf,否则等于
两个子节点的len和,在一个节点的cnt被修改时,已经线段树从下往上传递信息时
都依据此方法。
#include
#include
#include
#include
#include