Atlantis HDU - 1542 scanline template

I. content

 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<x2<=100000;0<=y1<y2<=100000), not necessarily integers. The values (x1; y1) and (x2;y2) are the coordinates of the top-left resp. bottom-right corner of the mapped area.

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 

Two, train of thought

  • Interval renewal+ Discretization
  • Interval update (optimization): because we add and delete operations in pairs, and the operation intervals are the same, we do not need to push () to mark the lower part of the lazy flag, because we use a certain interval, and we will not use the previously unused interval. Then there is no operation below the tag.

Three, code

#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 205;
struct Line {
	int st; //Represents 1-12 States 
	double s, e, x;
	bool operator < (const Line & w) const {
		return x < w.x; //In front of us, as small as x 
	}
} line[N];
struct Node {
	int cnt; //Represents the number of times included 
	double len; //The length of the interval to be included 
} tr[N << 2]; 
int n, cnt, t = 1; // cnt represents the number of elements in the array after discretization 
double fy[N], x1, x2, y1, y2; 
void build(int id, int l, int r) {
	tr[id].cnt = tr[id].len = 0;
	if (l == r) return;
	int mid = (l + r) >> 1;
	build(id << 1, l, mid);
	build(id << 1 | 1, mid + 1, r);
}
void pushup(int id, int l, int r) {
	if (tr[id].cnt){ // The range representing id is covered  
		tr[id].len = fy[r + 1] - fy[l]; //Because a point represents an interval, the interval of r is the length of [fy[r], fy[r + 1]] 
	} else if (l != r){ //If the whole range is not included, it is made up of son ranges 
		tr[id].len = tr[id << 1].len + tr[id << 1 | 1].len; 
	} else tr[id].len = 0; //leaf node  
}
void update(int id, int l, int r, int x, int y, int d) {
	if (x <= l && r <= y) {
		tr[id].cnt += d;
		pushup(id, l, r); //Update this interval in time because the father interval may need to use len of my interval 
		return;
	}
	int mid = (l + r) >> 1;
	if (x <= mid) update(id << 1, l, mid, x, y, d);
	if (y > mid) update(id << 1 | 1, mid + 1, r, x, y, d);
	pushup(id, l, r); 
} 
int  find(double y) {
	return lower_bound(fy + 1, fy + 1 + cnt, y) - fy; 
}
int main() {
	while (scanf("%d", &n), n) {
		for (int i = 1, j = 1; i <= n; i++) {
			scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
			line[j].s = y1, line[j].e = y2, line[j].x = x1, line[j].st = 1, fy[j++] = y1;
			line[j].s = y1, line[j].e = y2, line[j].x = x2, line[j].st = -1, fy[j++] = y2;
		}
		sort(line + 1, line + 1 + 2 * n);
		sort(fy + 1, fy + 1 + 2 * n);
		cnt = unique(fy + 1, fy + 1 + 2 * n) - fy - 1; //Get the number of elements after de duplication
		build(1, 1, cnt - 1); //A point represents an interval. There are CNT points in total, so there are only cnt-1 intervals
		double ans = 0;
		for (int i = 1; i <= 2 * n; i++) {
			ans += tr[1].len * (line[i].x - line[i - 1].x);
			update(1, 1, cnt - 1, find(line[i].s), find(line[i].e) - 1, line[i].st); //Here - 1 is because each point represents an interval. We can't include the interval represented by the point e 
		} 
		printf("Test case #%d\nTotal explored area: %.2lf\n\n", t++, ans); 
	}
	return 0;
}
Published 353 original articles, won praise 281, visited 50000+
Private letter follow

Posted by jess3333 on Sun, 26 Jan 2020 06:15:18 -0800