杭电 HDU ACM 1225 Atlantis (线段树 扫描线 离散化 最基本)

acm第一发扫描线问题,其实算法原理很好理解 ,但是具体实现起来还是遇到诸多问题,我尝试参考了网上两份对于解决 线段树表示区间问题的方法, 第一种是每个结点的真实值,比如对于更新离散化后的1 ~ 4区间,我们在线段树中更新的是1 ~ 3,这样单个结点也可以表示一个最小单位区间。 第二种那就是在建树的时候改变通常策略,1 ~ 10 为总区间,两个孩子为1 ~ 5 ,5 ~
10。

核心难点:当我们每次找到需要更新的区间,首先应该更新cover值,然后判断此时是被覆盖了,还是解除覆盖了,如果刚好被覆盖,那么此结点的sum值也就为结点真实区间值。如果是刚好解除覆盖,那么需要看看是否有他的孩子是被覆盖的,如果有,那么应该把两孩子值加到父亲sum上。

回溯时要判断每个子树根节点是否被覆盖,如果被覆盖那么就用当前父节点的值继续参与往上递归,如果未覆盖父节点就应该把孩子值更新上来,然后继续参与往上递归。  就会发现如果从根节点往下看,能够看到的第一层被覆盖的结点所表示的区间组合起来恰好就是总区间的sum值。

Atlantis

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)

Total Submission(s): 8948    Accepted Submission(s): 3833

Problem Description

There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. Some of these texts even include maps of parts of the island. But unfortunately, these maps describe different regions of Atlantis. Your
friend Bill has to know the total area for which maps exist. You (unwisely) volunteered to write a program that calculates this quantity.

Input

The input file consists of several test cases. Each test case starts with a line containing a single integer n (1<=n<=100) of available maps. The n following lines describe one map each. Each of these lines contains four numbers x1;y1;x2;y2
(0<=x1<x2<=100000;0<=y1<y2<=100000), not necessarily integers. The values (x1; y1) and (x2;y2) are the coordinates of the top-left resp. bottom-right corner of the mapped area.

The input file is terminated by a line containing a single 0. Don’t process it.

Output

For each test case, your program should output one section. The first line of each section must be “Test case #k”, where k is the number of the test case (starting with 1). The second one must be “Total explored area: a”, where a
is the total explored area (i.e. the area of the union of all rectangles in this test case), printed exact to two digits to the right of the decimal point.

Output a blank line after each test case.

Sample Input

2
10 10 20 20
15 15 25 25.5
0

Sample Output

Test case #1
Total explored area: 180.00 

Source

Mid-Central European Regional Contest 2000

version 1:

/*=============================================================================
#
#      Author: liangshu - cbam
#
#      QQ : 756029571
#
#      School : 哈尔滨理工大学
#
#      Last modified: 2015-08-11 12:30
#
#     Filename: A.cpp
#
#     Description:
#        The people who are crazy enough to think they can change the world, are the ones who do !
=============================================================================*/
#

#include<iostream>
#include<sstream>
#include<algorithm>
#include<cstdio>
#include<string.h>
#include<cctype>
#include<string>
#include<cmath>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
using namespace std;

const int INF = 2024;
struct line {
    double s, e, y, mark;
    line(double s, double e, double y, double ma):s(s),e(e),y(y), mark(ma){}
    bool friend operator < (line a, line  b){
        return a.y < b.y;
    }
};

struct Tree{
    int cover;
    int lft,rht;double sum;
}tree[INF<<2];

vector<double>X;
vector<line>L;
map<double, int>h;

void create(int root, int left, int right){
    tree[root].lft = left;
    tree[root].rht = right;
    tree[root].sum = 0;
    if(left + 1 != right){
        int mid = (left + right)/2;
        create(root<<1, left, mid);
        create(root<<1|1, mid, right);
    }
    return ;
}

void update(int root, int val, int left, int right){
    if(tree[root].lft >= left && tree[root].rht <= right){
        tree[root].cover += val;
        if(tree[root].cover){
            tree[root].sum =  X[tree[root].rht] - X[tree[root].lft];return ;
        }
        else{
            tree[root].sum = tree[root<<1].sum + tree[root<<1|1].sum;
            return ;
        }
    }
    if(tree[root].lft == tree[root].rht)return ;
    int mid = (tree[root].lft + tree[root].rht)/2;
    if(left < mid){
        update(root <<1, val, left, right);
    }
    if(right >= mid){
        update(root<<1|1,val,left, right);
    }
    if(!tree[root].cover)
    tree[root].sum = tree[root<<1].sum + tree[root<<1|1].sum;
}

int main(){
    int n,cs = 1;
    while(~scanf("%d", &n)&&n){
        h.clear();L.clear();X.clear();
        double x1, y1, x2, y2;
        for(int i = 1; i <= n; i++){
            scanf("%lf%lf%lf%lf",&x1, &y1, &x2, &y2);
            L.push_back(line(x1, x2, y1, 1));
            L.push_back(line(x1, x2, y2, -1));
            X.push_back(x1);X.push_back(x2);
        }
        sort(X.begin(), X.end());
        sort(L.begin(), L.end());
       X.erase(unique(X.begin(),X.end()), X.end());
       for(int i = 0; i < X.size(); i++){
           h[X[i]] = i;
       }
       create(1, 0, X.size() - 1);
       double ans = 0;int i;
       for( i = 0; i < L.size() - 1; i++){
           update(1, L[i].mark, h[L[i].s], h[L[i].e]);
               ans += (L[i + 1].y - L[i].y) * tree[1].sum;
       }
           update(1, L[i].mark, h[L[i].s], h[L[i].e]);
       printf("Test case #%d\nTotal explored area: %.2lf\n\n",cs++ , ans);
    }
}

version 2 :

/*=============================================================================
#
#      Author: liangshu - cbam
#
#      QQ : 756029571
#
#      School : 哈尔滨理工大学
#
#      Last modified: 2015-08-11 12:50
#
#     Filename: A.cpp
#
#     Description:
#        The people who are crazy enough to think they can change the world, are the ones who do !
=============================================================================*/
#

#include<iostream>
#include<sstream>
#include<algorithm>
#include<cstdio>
#include<string.h>
#include<cctype>
#include<string>
#include<cmath>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
using namespace std;
const int INF = 2222;

struct line
{
    double s, e, y, mark;
} L[INF];

double sum[INF<<2];
int cnt[INF<<2];
vector<double>dict;

bool cmp(line a, line b)
{
    return a.y < b.y;
}

void pushup(int rt, int l, int r)
{
    if(cnt[rt])
    {
        sum [rt] = dict[r + 1] - dict[l] ;
    }
    else
        sum[rt] = sum[rt<<1] + sum[rt<<1|1];
}
int  bin(double k, int len)
{
    int l = 0, r = len - 1;
    while (l <= r)
    {
        int mid = (l + r)>>1;
        if(dict[mid] == k)return mid;
        else if(dict[mid] > k)r = mid - 1;
        else l = mid + 1;
    }
    return -1;
}
void  update(int rt, int L, int R, int l ,int r, int val)
{
    if(L <= l && r <= R)
    {
        cnt[rt] += val;
        pushup(rt, l, r);
        return ;
    }
    int mid = (l + r)>>1;
    if(L <= mid)update(rt<<1, L, R, l , mid, val);
    if(R > mid)update(rt<<1|1,L, R, mid + 1, r, val);
    pushup(rt,l, r);
}

int main()
{
    int n,cs = 1;
    while(scanf("%d", &n) != EOF && n)
    {
        memset(sum, 0, sizeof(sum));
        int t = 0;
        for(int i = 1; i <= n; i++)
        {
            double x1,y1,x2,y2;
            scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
            dict.push_back (x1);
            L[t].s = x1;
            L[t].e = x2;
            L[t].y = y1;
            L[t++].mark = 1;
            dict.push_back(x2);
            L[t].s = x1;
            L[t].e = x2;
            L[t].y = y2;
            L[t++].mark = -1 ;
        }
        sort(L , L + t, cmp);
        sort(dict .begin(), dict.end());
        dict.erase (unique(dict.begin(), dict.end()), dict.end());
        double ans = 0;
        for(int i = 0; i < t ; i ++ )
        {
            int l = bin(L[i].s, dict.size());
            int r = bin(L[i].e, dict.size()) - 1;
            if(l <= r)
                update(1, l, r, 0, dict.size() - 1, L[i].mark);
            ans += sum[1] * (L[i + 1].y - L[i].y);
        }
        printf("Test case #%d\nTotal explored area: %.2lf\n\n",cs++ , ans);
    }
    return 0 ;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-12-13 02:35:20

杭电 HDU ACM 1225 Atlantis (线段树 扫描线 离散化 最基本)的相关文章

HDU 1542 Atlantis (线段树 + 扫描线 + 离散化)

Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 8998    Accepted Submission(s): 3856 Problem Description There are several ancient Greek texts that contain descriptions of the fabled i

poj 1151 Atlantis (线段树+扫描线+离散化)

Atlantis Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 18061   Accepted: 6873 Description There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. Some of these texts even include maps of parts of

HDU 1542 Atlantis(线段树扫描线)

http://acm.hdu.edu.cn/showproblem.php?pid=1542 Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 6788    Accepted Submission(s): 2970 Problem Description There are several ancient Greek

杭电 HDU ACM 1397 Goldbach&#39;s Conjecture

Goldbach's Conjecture Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 4976    Accepted Submission(s): 1901 Problem Description Goldbach's Conjecture: For any even number n greater than or equal

杭电 HDU ACM 5186 zhx&#39;s submissions

zhx's submissions Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 1892    Accepted Submission(s): 507 Problem Description As one of the most powerful brushes, zhx submits a lot of code on many

杭电 HDU ACM 1025 Constructing Roads In JGShining&#39;s Kingdom

Constructing Roads In JGShining's Kingdom Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 17732    Accepted Submission(s): 5023 Problem Description JGShining's kingdom consists of 2n(n is no mo

hdu 1542 Atlantis(线段树&amp;扫描线&amp;面积并)

Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 6386    Accepted Submission(s): 2814 Problem Description There are several ancient Greek texts that contain descriptions of the fabled i

杭电HDU ACM Uncle Tom&#39;s Inherited Land*(二分图匹配 建模)

Uncle Tom's Inherited Land* Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 2496    Accepted Submission(s): 1028 Special Judge Problem Description Your old uncle Tom inherited a piece of land f

hdu1542 Atlantis (线段树+扫描线+离散化)

Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 9032    Accepted Submission(s): 3873 Problem Description There are several ancient Greek texts that contain descriptions of the fabled i