[HNOI2012]三角形覆盖问题

#include<cmath>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<iostream>
using namespace std;
class Dread{
    private:
        bool isdigit(char ch) { return ch >= '0' && ch <= '9'; }
        bool isalpha(char ch) { return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'); }
        void Getchar(int &tmp){
            char ch; tmp = 0; bool b = true;
            while (ch = getchar()){
				if (ch == '-') b = false;
				if (isdigit(ch)) break;
            }
			for (; isdigit(ch); ch = getchar()) tmp = tmp * 10 + ch - '0';
        	if (!b) tmp = -tmp;
		}
        void Getchar(char &tmp){
            while (tmp = getchar()) if (isalpha(tmp)) break;
        }
    public:
        int Int(){ int x; Getchar(x); return x; }
        char Ch(){ char x; Getchar(x); return x; }
}Read;
const int maxn = 101111;
const int maxm = 1010000;
struct zy{
	int x, y, d, l, r;
	bool operator < (const zy a) const { return y < a.y; }
	bool operator > (const zy b) const { return l <= b.l && b.r <= r; }
}a[maxn];
int q[maxn];
int sum[maxm], n;
int next[maxn], last[maxn];
bool b[maxn];
int maxh = 0;
void init(){
	n = Read.Int();
	for (int i = 1; i <= n; i ++){
		a[i].x = Read.Int(), a[i].y = Read.Int(), a[i].d = Read.Int();
		a[i].l = a[i].x, a[i].r = a[i].x + a[i].d;
		next[i] = i + 1, last[i] = i - 1;
		maxh = max(maxh, a[i].d + a[i].y);
	}
}
int head;
void Delete(int j){
	if (j == head) head = next[j];
	last[next[j]] = last[j];
	next[last[j]] = next[j];
	b[j] = false;
}
void work(){
	sort(a + 1, a + n + 1);
	memset(b, 1, sizeof(b));
	double len = 0;
	head = 1;
	for (int i = 1; i <= n && a[i].y == a[1].y; i ++)
		for (int j = a[i].l; j < a[i].r; j ++){
			if (!sum[j]) len ++;
			sum[j] ++;
		}
	double ans = 0;
	for (int i = a[1].y + 1; i <= maxh; i ++){
		double lastlen = len;
		int ww = 0;
		for (int j = head; a[j].y < i && j <= n; j = next[j]){
			a[j].r --;
			if (a[j].r < a[j].x) Delete(j);
			else {
				sum[a[j].r] --;
				if (!sum[a[j].r]) len --;
				q[++ww] = j;
			}
		}
		ans += (lastlen + len) * 1.0 / 2.0;
		for (int j = head; a[j].y <= i && j <= n; j = next[j])
			if (a[j].y == i){
				int k;
				for (k = 1; k <= ww; k ++){
					if (!b[q[k]]) continue; 
					if (a[q[k]] > a[j]){ 
						Delete(j);
						break;
					}
					if (a[j] > a[q[k]]){
						Delete(q[k]);
						for (int kk = a[q[k]].l; kk < a[q[k]].r; kk ++){
							sum[kk] --;
							if (!sum[kk]) len --;
						}
					}
				}
				if (k <= ww) continue;
				for (int kk = a[j].l; kk < a[j].r; kk ++){
					if (!sum[kk]) len ++;
					sum[kk] ++;
				}
			}
	}
	printf("%.1lf\n", ans);
}
int main(){
	init();
	work();
	return 0;
}

2731: [HNOI2012]三角形覆盖问题

Time Limit: 20 Sec  Memory Limit: 128 MB
Submit: 172  Solved: 95
[ Submit][ Status]

Description

二维平面中,给定    N个等腰直角三角形(每个三角形的两条直角边分别
平行于坐标轴,斜边从左上到右下)。我们用三个非负整数( x, y, d)来描
述这样一个三角形,三角形三个顶点的坐标
 
分别为( x, y), ( x + d, y)和( x, y +     d)。要求计算这    N个三角形所覆盖的总面
积。例如,下图有 3 个三角形,覆盖的总面积为 11.0。
[HNOI2012]三角形覆盖问题_第1张图片

Input

输入文件第一行为一个正整数N,表示三角形的个数。接下来N

行每行有用空格隔开的三个非负整数,  x,y   , d,描述一个三角

形的顶点坐标,分别为

(    x, y), (x+ d, y), (  x,y+d)

其中 x, y,d 满足0≤   x, y, d≤1000000

对于50%的数据,1≤         N≤500

100%的数据,1≤N≤10000

 

Output

仅包含一行,为一个实数    S   ,表示所有三角形所覆盖的总面积,输出恰

好保留一位小数。输入数据保证     S≤2^31

Sample Input

3 .
1 1 4
2 0 2
3 2 2

Sample Output

11.0

HINT

Source

day2


从最低点弄根扫描线,一直到最高点,每次扫描线++

两根扫描之间的面积,就是下面那根扫描线被覆盖的长度+上面那根扫描线被非底边覆盖的长度,然后除以2。

 然后最坏是100000 * 1000000

直接上代码








你可能感兴趣的:([HNOI2012]三角形覆盖问题)