标签:更新 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