您的位置:首页 > 其它

[HNOI2012]三角形覆盖问题

2014-01-29 21:11 162 查看

#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

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



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

直接上代码

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: