标签:更新 line describe 距离 poj1151 output tracking ber ring
| Time Limit: 1000MS | Memory Limit: 10000K | |
| Total Submissions: 16882 | Accepted: 6435 |
Description
Input
Output
Sample Input
2 10 10 20 20 15 15 25 25.5 0
Sample Output
Test case #1 Total explored area: 180.00
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define maxn 202
#define lson l, mid, rt << 1
#define rson mid, r, rt << 1 | 1
using namespace std;
struct Node {
double y1, y2, len;
int covers;
} T[maxn << 2];
struct Node2 {
double x, y1, y2;
int isLeft;
} xNode[maxn];
double yNode[maxn];
bool cmp(Node2 a, Node2 b) {
return a.x < b.x;
}
void pushUp(int l, int r, int rt) {
if(T[rt].covers > 0)
T[rt].len = T[rt].y2 - T[rt].y1;
else if(r - l == 1) T[rt].len = 0.0;
else T[rt].len = T[rt << 1].len + T[rt << 1 | 1].len;
}
void build(int l, int r, int rt) {
T[rt].covers = 0;
T[rt].y1 = yNode[l];
T[rt].y2 = yNode[r];
T[rt].len = 0.0;
if(r - l == 1) return;
int mid = (l + r) >> 1;
build(lson);
build(rson);
}
void update(Node2 x, int l, int r, int rt) {
if(x.y1 == T[rt].y1 && x.y2 == T[rt].y2) {
T[rt].covers += x.isLeft;
pushUp(l, r, rt);
return;
}
int mid = (l + r) >> 1;
if(x.y2 <= yNode[mid]) update(x, lson);
else if(x.y1 >= yNode[mid]) update(x, rson);
else {
Node2 x1 = x, x2 = x;
x1.y2 = x2.y1 = yNode[mid];
update(x1, lson);
update(x2, rson);
}
pushUp(l, r, rt);
}
int main() {
//freopen("stdin.txt", "r", stdin);
int n, i, id, cas = 1;
double x1, y1, x2, y2, sum;
while(scanf("%d", &n), n) {
for(i = id = 0; i < n; ++i) {
scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
yNode[id] = y1;
xNode[id].x = x1;
xNode[id].y1 = y1;
xNode[id].y2 = y2;
xNode[id++].isLeft = 1;
yNode[id] = y2;
xNode[id].x = x2;
xNode[id].y1 = y1;
xNode[id].y2 = y2;
xNode[id++].isLeft = -1;
}
sort(yNode, yNode + id);
build(0, id - 1, 1);
sort(xNode, xNode + id, cmp);
update(xNode[0], 0, id - 1, 1);
for(i = 1, sum = 0.0; i < id; ++i) {
sum += T[1].len * (xNode[i].x - xNode[i-1].x);
update(xNode[i], 0, id - 1, 1);
}
printf("Test case #%d\nTotal explored area: %.2lf\n\n", cas++, sum);
}
return 0;
}#include <stdio.h>
#include <algorithm>
#define maxn 202
#define lson l, mid, rt << 1
#define rson mid, r, rt << 1 | 1
using std::sort;
struct Node{
double y1, y2, height; //y1, y2记录y坐标离散前的值
int coverTimes;
} tree[maxn << 2]; //区间树
double yArr[maxn]; //垂直于Y轴的割线
struct node{
double x, y1, y2;
int isLeftEdge;
} xArr[maxn]; //垂直于X轴的割线
bool cmp(node a, node b){ return a.x < b.x; }
void build(int l, int r, int rt)
{
tree[rt].coverTimes = 0;
tree[rt].height = 0;
tree[rt].y1 = yArr[l];
tree[rt].y2 = yArr[r];
if(r - l == 1) return;
int mid = (l + r) >> 1;
build(lson);
build(rson);
}
void getSweepLinesHeight(int l, int r, int rt)
{//因为存在线段覆盖的情况,所以长线段结束并不能代表扫描线长度为0
if(tree[rt].coverTimes > 0){
tree[rt].height = tree[rt].y2 - tree[rt].y1;
}else if(r - l == 1){
tree[rt].height = 0;
}else tree[rt].height = tree[rt << 1].height + tree[rt << 1 | 1].height;
}
void update(node xNode, int l, int r, int rt)
{
if(xNode.y1 == tree[rt].y1 && xNode.y2 == tree[rt].y2){
tree[rt].coverTimes += xNode.isLeftEdge;
getSweepLinesHeight(l, r, rt);
return;
} //include r - l == 1
int mid = (l + r) >> 1;
if(xNode.y2 <= yArr[mid]) update(xNode, lson);
else if(xNode.y1 >= yArr[mid]) update(xNode, rson);
else{
node temp = xNode;
temp.y2 = yArr[mid];
update(temp, lson);
temp = xNode; temp.y1 =yArr[mid];
update(temp, rson);
}
getSweepLinesHeight(l, r, rt); //Attention!
}
int main()
{
//freopen("stdin.txt", "r", stdin);
int n, i, cas = 1, id;
double x1, y1, x2, y2, sum;
while(scanf("%d", &n), n){
for(i = id = 0; i < n; ++i){
scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
yArr[id] = y1; xArr[id].x = x1;
xArr[id].isLeftEdge = 1; //1表示左。-1表示右
xArr[id].y1 = y1; xArr[id++].y2 = y2;
yArr[id] = y2; xArr[id].x = x2;
xArr[id].isLeftEdge = -1;
xArr[id].y1 = y1; xArr[id++].y2 = y2;
}
sort(yArr, yArr + id);
sort(xArr, xArr + id, cmp);
build(0, id - 1, 1);
update(xArr[0], 0, id - 1, 1);
for(i = 1, sum = 0; i < id; ++i){
sum += tree[1].height * (xArr[i].x - xArr[i - 1].x);
update(xArr[i], 0, id - 1, 1);
}
printf("Test case #%d\nTotal explored area: %.2lf\n\n", cas++, sum);
}
return 0;
}标签:更新 line describe 距离 poj1151 output tracking ber ring
原文地址:http://www.cnblogs.com/slgkaifa/p/6953123.html