POJ 1151 HDU 1542 Atlantis(掃描線)

來源:互聯網
上載者:User

標籤:des   style   blog   http   color   os   io   strong   

題目大意就是:去一個地方探險,然後給你一些地圖描述這個地方,每個描述是一個矩形的右下角和左上方。地圖有些地方是重疊的,所以讓你求出被描述的地方的總面積。

掃描線的第一道題,想了又想,嘯爺還給我講了講,終於有點理解了啊。

先說掃描線:書上說掃描線不是一個物體,而是一個概念。在計算幾何中的作用類似於圖論中的bfs與dfs。所以還是需要多做題目來體會一下啊。

這道題目的做法是:離散化x座標,然後按照y座標的大小進行排序,每一條儲存它的左邊界的位置與右邊界的位置,以及自身的高度。還有就是如果是下邊初始為1,上邊初始為-1。

接下來就是掃描線了:按照y值排序後的數組,開始遍曆。先二分尋找它在離散數組中下表的位置。找到之後按他儲存的邊界的標記,進行更新。這裡的區間更新用的是線段樹的維護。我們以離散化後數組建樹。每個節點儲存它此時有多少個上界與下界的和,表示他是否存在矩形。如果存在的話每個節點中用sun數組儲存這個矩形x值的差值(通過這個離散區間的下標,做減法就是離散的x的差值)。最後的時候乘上y的差值。就是掃描到的矩陣的面積。

Atlantis
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 17207   Accepted: 6549

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 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

210 10 20 2015 15 25 25.50

Sample Output

Test case #1Total explored area: 180.00 

Source

Mid-Central European Regional Contest 2000
#include <algorithm>#include <iostream>#include <stdlib.h>#include <string.h>#include <iomanip>#include <stdio.h>#include <string>#include <queue>#include <cmath>#include <stack>#include <ctime>#include <map>#include <set>#define eps 1e-12///#define M 1000100#define LL __int64///#define LL long long///#define INF 0x7ffffff#define INF 0x3f3f3f3f#define PI 3.1415926535898#define zero(x) ((fabs(x)<eps)?0:x)using namespace std;const int maxn = 5010;struct node{    double l, r, h;    int x;} f[maxn];double sum[maxn<<2];int cnt[maxn];double dc[maxn];bool cmp(node a, node b){    return a.h < b.h;}int Find(double x, double a[], int n){    int l = 0;    int r = n-1;    while(l <= r)    {        int mid = (l+r)/2;        if(a[mid] == x) return mid;        if(a[mid] > x) r = mid-1;        else l = mid+1;    }    return -1;}void Up(int l, int r, int site){    if(cnt[site]) sum[site] = dc[r+1]-dc[l];    else if(l == r) sum[site] = 0;    else sum[site] = sum[site<<1]+sum[site<<1|1];}void Update(int l, int r, int L, int R, int d, int site){    if(L <= l && r <= R)    {        cnt[site] += d;        Up(l, r, site);        return;    }    int mid = (l+r)>>1;    if(L <= mid) Update(l, mid, L, R, d, site<<1);    if(R > mid) Update(mid+1, r, L, R, d, site<<1|1);    Up(l, r, site);}int main(){    int n;    int Case = 1;    while(cin >>n)    {        if(!n) break;        double x1, y1, x2, y2;        int m = 0;        for(int i = 0; i < n; i++)        {            scanf("%lf %lf %lf %lf",&x1, &y1, &x2, &y2);            dc[m] = x1;            f[m].l = x1;            f[m].r = x2;            f[m].h = y1;            f[m++].x = 1;            dc[m] = x2;            f[m].l = x1;            f[m].r = x2;            f[m].h = y2;            f[m++].x = -1;        }        sort(dc, dc+m);        sort(f, f+m, cmp);        int k = unique(dc, dc+m)-dc;        memset(cnt, 0 , sizeof(cnt));        memset(sum, 0 , sizeof(sum));        double ans = 0;        for(int i = 0; i < m-1; i++)        {            int l = Find(f[i].l, dc, k);            int r = Find(f[i].r, dc, k)-1;            if(l <= r) Update(0, k-1, l, r, f[i].x, 1);            ans += sum[1]*(f[i+1].h-f[i].h);        }        printf("Test case #%d\n",Case++);        printf("Total explored area: %.2f\n\n",ans);    }    return 0;}


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.