poj 1151 Atlantis

来源:互联网 发布:telnet端口开启 编辑:程序博客网 时间:2024/04/23 19:36

类型:离散化

题目:http://poj.org/problem?id=1151

来源:Mid-Central European Regional Contest 2000

思路【一】:

(1)使用map离散化

(2)对每个矩形进行覆盖操作

(3)统计覆盖的区域面积和

//poj 1151 Atlantis// wa ac 312K 32MS#include <iostream>#include <map>#include <algorithm>#include <cstdio>#include <cstring>using namespace std;const int MAXM = 2610;int n, cntx, cnty, cas = 1;bool endd[210][210];double dax[MAXM], day[MAXM];map<double, int> mpx, mpy, mpxx, mpyy;map<double, int>::iterator it;struct pot {    double x1, y1, x2, y2;}p[MAXM];void solve() {    int i, j, k;    cntx = cnty = 1;    for(it = mpxx.begin(); it != mpxx.end(); ++it)        mpx[it->first] = cntx, dax[cntx++] = it->first;    for(it = mpyy.begin(); it != mpyy.end(); ++it)        mpy[it->first] = cnty, day[cnty++] = it->first;    for(i = 1; i <= n; ++i) {        int x1 = mpx[p[i].x1];        int y1 = mpy[p[i].y1];        int x2 = mpx[p[i].x2];        int y2 = mpy[p[i].y2];        for(j = x1; j < x2; ++j)        for(k = y1; k < y2; ++k)            endd[j][k] = true;    }    double sum = 0.0;    for(i = 1; i < cntx - 1; ++i)    for(j = 1; j < cnty - 1; ++j)        if(endd[i][j]) {            sum += (dax[i + 1] - dax[i]) * (day[j + 1] - day[j]);        }    printf("Test case #%d\n", cas++);    printf("Total explored area: %.2lf\n\n", sum);}int main() {    double x1, x2, y1, y2;    int i;    while(scanf("%d", &n) != EOF, n) {        cntx = cnty = 1;        mpx.clear();        mpy.clear();        mpxx.clear();        mpyy.clear();        memset(endd, false, sizeof(endd));        for(i = 1; i <= n; ++i) {            scanf("%lf %lf %lf %lf", &x1, &y1, &x2, &y2);            p[i].x1 = x1, p[i].x2 = x2, p[i].y1 = y1, p[i].y2 = y2;            if(mpxx.count(x1) == 0)                mpxx[x1] = cntx;            if(mpyy.count(y1) == 0)                mpyy[y1] = cnty;            if(mpxx.count(x2) == 0)                mpxx[x2] = cntx;            if(mpyy.count(y2) == 0)                mpyy[y2] = cnty;        }        solve();    }    return 0;}

思路【二】:

(1)对y坐标离散化,对x坐标建立扫描线

(2)以y坐标建立线段树

(3)插入线段【x扫描线】,每插入一次,统计可得到的矩形面积

(4)对于每条线段,如果有p[t].c > 0 即可统计,当p[t].c = 0时该块矩形扫描完成,不再进行统计

//poj 1151 Atlantis//ac 224K 0MS#include <iostream>#include <sstream>#include <string>#include <queue>#include <stack>#include <map>#include <algorithm>#include <cmath>#include <cstdio>#include <cstdlib>#include <cstring>using namespace std;#define FOR(i,a,b) for(i = (a); i < (b); ++i)#define FORE(i,a,b) for(i = (a); i <= (b); ++i)#define FORD(i,a,b) for(i = (a); i > (b); --i)#define FORDE(i,a,b) for(i = (a); i >= (b); --i)const int MAXN = 1010;int n, m, len, t = 1;struct node {    int l, r, c;    double len, sum;}p[MAXN * 5];struct line {    double x, y1, y2;    int sign;}l[MAXN];double Y[MAXN];void creat(int t, int l, int r) {    int mid = (l + r) >> 1;    p[t].l = l, p[t].r = r;    p[t].c = 0, p[t].sum = 0;    p[t].len = Y[r] - Y[l];    if(l + 1 < r) {        creat(t * 2, l, mid);        creat(t * 2 + 1, mid, r);        return;    }}void insert(int t, int l, int  r, int flag) {    int mid = (p[t].l + p[t].r) / 2;    if(p[t].l == l && p[t].r == r) {        (flag == true) ? ++p[t].c : --p[t].c;    }    else {        if(r <= mid)            insert(t * 2, l, r, flag);        else if(l >= mid)            insert(t * 2 + 1, l, r, flag);        else {            insert(t * 2, l, mid, flag);            insert(t * 2 + 1, mid, r, flag);        }    }    if(p[t].c > 0)        p[t].sum = p[t].len;    else if(p[t].r - p[t].l > 1)        p[t].sum = p[t * 2].sum + p[t * 2 + 1].sum;    else // !!!        p[t].sum = 0;}int cmp(line a, line b) {    return a.x < b.x;}int find(double key) {    int l = 0, r = len - 1, mid;    while(l <= r) {        mid = (l + r) >> 1;        if(Y[mid] >= key)            r = mid - 1;        else            l = mid + 1;    }    return l;}void solve() {    int i;    double x1, x2, y1, y2, ans = 0;    m = 0;    FORE(i, 1, n) {        scanf("%lf %lf %lf %lf", &x1, &y1, &x2, &y2);        Y[m] = y1; l[m].x = x1; l[m].y1 = y1; l[m].y2 = y2; l[m++].sign = 1;        Y[m] = y2; l[m].x = x2; l[m].y1 = y1; l[m].y2 = y2; l[m++].sign = 0;    }    sort(Y, Y + m);    sort(l, l + m, cmp);    len = unique(Y, Y + m) - Y;    creat(1, 0, len - 1);    FOR(i, 0, m) {        if(l[i].sign)            insert(1, find(l[i].y1), find(l[i].y2), 1);        else            insert(1, find(l[i].y1), find(l[i].y2), 0);        ans += p[1].sum * (l[i + 1].x - l[i].x);    }    printf("Test case #%d\n", t++);    printf("Total explored area: %.2lf\n\n", ans);}int main() {    while(scanf("%d", &n) != EOF, n) {        solve();    }    return 0;}/*210 10 20 2015 15 25 25.50*/




原创粉丝点击