• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            posts - 7,comments - 3,trackbacks - 0

             1043: Atlantis


            ResultTIME LimitMEMORY LimitRun TimesAC TimesJUDGE
            3s8192K431155Standard

            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 containsfour 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 it1.

            Output

            For each test case, your program should output one section. The first line of each section must be “Testcase #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


            題目的意思是給定n個(gè)矩形的2n個(gè)坐標(biāo),求矩形的覆蓋面積。如果開(kāi)一個(gè)大的bool數(shù)組,將覆蓋過(guò)的部分更新為true,再?gòu)念^到尾掃描一遍,在坐標(biāo)范圍比較小的情況下,可以求解。但是如果坐標(biāo)x,y的取值范圍很大,比如[-10^8,10^8],用上面這個(gè)方法就不能求解了;而且坐標(biāo)還有可能是實(shí)數(shù),上面的方法就更加不可行了,需要尋找一種新的解法,就是下面要說(shuō)到的“離散化”。
                注意到要表示一個(gè)矩形,只需要知道其2個(gè)頂點(diǎn)的坐標(biāo)就可以了(最左下,最右上)。可以用2個(gè)數(shù)組x[0...2n-1],y[0...2n-1]記錄下矩形Ri的2個(gè)坐標(biāo)(x1,y1),(x2,y2),然后將數(shù)組x[0...xn-1],y[0...2n-1]排序,為下一步的掃描線作準(zhǔn)備,這就是離散化的思想。這題還可以用線段樹(shù)做進(jìn)一步優(yōu)化,但是這里只介紹離散化的思想。
                看下面這個(gè)例子:有2個(gè)矩形(1,1),(3,3)和(2,2),(4,4)。如圖:
                圖中虛線表示掃描線,下一步工作只需要將這2個(gè)矩形覆蓋過(guò)的部分的bool數(shù)組的對(duì)應(yīng)位置更新為true,接下去用掃描線從左到右,從上到下掃描一遍,就可以求出矩形覆蓋的總面積。
                這個(gè)圖對(duì)應(yīng)的bool數(shù)組的值如下:
                1 1 0                       1 2 3
                1 1 1       <---->       4 5 6
                0 1 1                       7 8 9

            代碼:

            #include<stdio.h>
            #include
            <iostream>
            #include
            <algorithm>
            #define MAXN 201
            using namespace std;

            struct Node
            {
                
            int l, r;//線段樹(shù)的左右整點(diǎn)
                int c;//c用來(lái)記錄重疊情況
                double cnt, lf, rf;//
                
            //cnt用來(lái)計(jì)算實(shí)在的長(zhǎng)度,rf,lf分別是對(duì)應(yīng)的左右真實(shí)的浮點(diǎn)數(shù)端點(diǎn)
            } segTree[MAXN * 3];
            struct Line
            {
                
            double x, y1, y2;
                
            int f;
            } line[MAXN];
            //把一段段平行于y軸的線段表示成數(shù)組 ,
            //x是線段的x坐標(biāo),y1,y2線段對(duì)應(yīng)的下端點(diǎn)和上端點(diǎn)的坐標(biāo)
            //一個(gè)矩形 ,左邊的那條邊f(xié)為1,右邊的為-1,
            //用來(lái)記錄重疊情況,可以根據(jù)這個(gè)來(lái)計(jì)算,nod節(jié)點(diǎn)中的c

            bool cmp(Line a,Line b)//sort排序的函數(shù)
            {
                
            return a.x < b.x;
            }

            double y[MAXN];//記錄y坐標(biāo)的數(shù)組
            void Build(int t,int l,int r)//構(gòu)造線段樹(shù)
            {
                segTree[t].l 
            = l;
                segTree[t].r 
            = r;
                segTree[t].cnt 
            = segTree[t].c = 0;
                segTree[t].lf 
            = y[l];
                segTree[t].rf 
            = y[r];
                
            if (l + 1 == r) return;
                
            int mid = (l + r) >> 1;
                Build(t 
            << 1, l, mid);
                Build(t 
            << 1 | 1, mid, r);//遞歸構(gòu)造
            }
            void calen(int t)//計(jì)算長(zhǎng)度
            {
                
            if (segTree[t].c > 0)
                {
                    segTree[t].cnt 
            = segTree[t].rf - segTree[t].lf;
                    
            return;
                }
                
            if (segTree[t].l + 1 == segTree[t].r)
                    segTree[t].cnt 
            = 0;
                
            else
                    segTree[t].cnt 
            = segTree[t << 1].cnt + segTree[t << 1 | 1].cnt;
            }
            void update(int t, Line e)//加入線段e,后更新線段樹(shù)
            {
                
            if (e.y1 == segTree[t].lf && e.y2 == segTree[t].rf)
                {
                    segTree[t].c 
            += e.f;
                    calen(t);
                    
            return;
                }
                
            if (e.y2 <= segTree[t << 1].rf)
                    update(t 
            << 1, e);
                
            else
                
            if(e.y1 >= segTree[t << 1 | 1].lf)
                    update(t 
            << 1 | 1, e);
                
            else
                {
                    Line tmp 
            = e;
                    tmp.y2 
            = segTree[t << 1].rf;
                    update(t 
            << 1, tmp);
                    tmp 
            = e;
                    tmp.y1 
            = segTree[t << 1 | 1].lf;
                    update(t 
            << 1 | 1, tmp);
                }
                calen(t);
            }
            int main()
            {
                
            int i, n, t, iCase = 0;
                
            double x1, y1, x2, y2;
                
            while(scanf("%d"&n) && n)
                {
                    iCase
            ++;
                    t 
            = 1;
                    
            for(i = 1; i <= n; i++)
                    {
                        scanf(
            "%lf%lf%lf%lf"&x1, &y1, &x2, &y2);
                        line[t].x 
            = x1;
                        line[t].y1 
            = y1;
                        line[t].y2 
            = y2;
                        line[t].f 
            = 1;
                        y[t] 
            = y1;
                        t
            ++;
                        line[t].x 
            = x2;
                        line[t].y1 
            = y1;
                        line[t].y2 
            = y2;
                        line[t].f 
            = -1;
                        y[t] 
            = y2;
                        t
            ++;
                    }
                    sort(line 
            + 1, line + t, cmp);
                    sort(y 
            + 1, y + t);
                    Build(
            11, t - 1);
                    update(
            1, line[1]);
                    
            double res = 0;
                    
            for(i = 2; i < t; i++)
                    {
                        res 
            += segTree[1].cnt * (line[i].x - line[i - 1].x);
                        update(
            1, line[i]);
                    }
                    printf(
            "Test case #%d\n", iCase);
                    printf(
            "Total explored area: %.2lf\n\n", res);
                }
                
            return 0;
            }
            posted on 2011-10-25 23:52 LLawliet 閱讀(255) 評(píng)論(0)  編輯 收藏 引用 所屬分類(lèi): 線段樹(shù)

            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


            91精品国产91热久久久久福利 | 国产精品99久久久精品无码 | 久久99国内精品自在现线| av无码久久久久不卡免费网站| 国产午夜福利精品久久2021| 精品乱码久久久久久夜夜嗨| 久久天天躁狠狠躁夜夜avapp | 精品熟女少妇aⅴ免费久久| 2021国产精品久久精品| 久久久久成人精品无码中文字幕| 精品无码久久久久久久动漫| 天天躁日日躁狠狠久久| 热综合一本伊人久久精品| 99热成人精品热久久669| 性做久久久久久免费观看| 日本一区精品久久久久影院| 亚洲国产精品无码久久久秋霞2| 久久久久久久综合日本| segui久久国产精品| 人妻少妇久久中文字幕一区二区| 久久涩综合| 大蕉久久伊人中文字幕| 久久精品国产精品国产精品污| 国产69精品久久久久久人妻精品| 久久久这里有精品中文字幕| 99久久www免费人成精品| 久久人妻少妇嫩草AV无码专区 | 亚洲乱亚洲乱淫久久| 久久久久久久久久久久中文字幕 | 国产精品久久久久久吹潮| 国内精品伊人久久久久777| 久久精品国产精品亚洲艾草网美妙| 99久久婷婷免费国产综合精品| 亚洲欧美日韩久久精品第一区| 久久久久亚洲AV片无码下载蜜桃| 欧美日韩精品久久久免费观看| 日韩一区二区三区视频久久| 亚洲国产精品成人AV无码久久综合影院 | 99久久精品国产一区二区| 久久人人爽人人爽人人av东京热| 久久精品无码一区二区WWW|