zoukankan      html  css  js  c++  java
  • POJ 1151 Atlantis(扫描线)

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

    题目中文翻译:

    POJ 1151 Atlantis

    Time Limit: 1000MS

     

    Memory Limit: 10000K

    Total Submissions: 25769

     

    Accepted: 9477

    Description

    有几个古希腊文本包含传说中的亚特兰蒂斯岛的描述。 其中一些文本甚至包括岛屿部分地图。 但不幸的是,这些地图描述了亚特兰蒂斯的不同区域。 您的朋友Bill必须知道地图的总面积。 你(不明智地)自告奋勇写了一个计算这个数量的程序。

    Input

    输入包含几个测试用例。 每个测试用例都以一行包含一个整数n(1 <= n <= 100)开始,指示可用的地图。以下n行描述了每个地图。 这些行中的每一行包含四个数字x1; y1; x2; y2(0 <= x1 <x2 <= 100000; 0 <= y1 <y2 <= 100000),不一定是整数。 值(x1; y1)和(x2; y2)是地图左上角和右下角的坐标。

    输入文件以包含单个0的行作为终止。不处理它。

    Output

    对于每个测试用例,您的程序应输出一个部分。 每个部分的第一行必须是“Test case #k”,其中k是测试用例的编号(从1开始)。 第二个必须是“Total explored area:a”,其中a是总探索区域(即此测试用例中所有矩形的覆盖区域),精确到小数点后两位数。

    在每个测试用例后输出一个空行。

    Sample Input

    2

    10 10 20 20

    15 15 25 25.5

    0

    Sample Output

    Test case #1

    Total explored area: 180.00

    解题思路:

    本人太菜,无法描述,请看大佬详解:AKIOI

    AC代码:

    (由此大佬博客借鉴而来:code)

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<algorithm>
     4 
     5 using namespace std;
     6 
     7 struct kkk{//线段树 
     8     int l,r;//线段树的左右整点
     9     int c;//c用来记录重叠情况
    10     double cnt,lf,rf;//cnt用来计算实在的长度,lf,rf分别是对应的左右真实的浮点数端点 
    11 }s[603];
    12 
    13 struct k2{
    14     double x,y1,y2;
    15     int f;
    16 }l[603]; 
    17 //把一段段平行于y轴的线段表示成数组 ,
    18 //x是线段的x坐标,y1,y2线段对应的下端点和上端点的坐标 
    19 //一个矩形 ,左边的那条边f为1,右边的为-1,
    20 //用来记录重叠情况,可以根据这个来计算,kkk节点中的c 
    21 
    22 double y[201];//记录y坐标的数组
    23 
    24 bool cmp(k2 a,k2 b) {
    25     return a.x < b.x;
    26 }
    27 
    28 void build(int t,int l,int r) {
    29     s[t].l = l;s[t].r = r;
    30     s[t].cnt = s[t].c = 0;
    31     s[t].lf = y[l];
    32     s[t].rf = y[r];
    33     if(l + 1 == r) return ;
    34     int mid = (l + r) >> 1;
    35     build(t << 1,l,mid);
    36     build(t << 1 | 1,mid,r);
    37 }
    38 
    39 void calen(int t) {//计算长度
    40     if(s[t].c > 0) {// t对应对节点有线段覆盖
    41         s[t].cnt = s[t].rf - s[t].lf; 
    42         return ;
    43     }
    44     // 现在是t对应的线段没有完整的被覆盖,但是他的孩子节点可能部分被覆盖
    45     if(s[t].l + 1 == s[t].r) s[t].cnt = 0;//线段树叶子结点,代表一个点,特判,长度为0
    46     else s[t].cnt = s[t<<1].cnt + s[t<<1|1].cnt;//否则,用孩子的和来表示
    47 }
    48 
    49 
    50 void update(int t,k2 e) {//加入线段e,后更新线段树
    51     if(e.y1 == s[t].lf && e.y2 == s[t].rf) {//如果正好找到区间 
    52         s[t].c += e.f; 
    53         calen(t);
    54         return ;
    55     }
    56     if(e.y2 <= s[t<<1].rf) update(t<<1,e);//下传左儿子 
    57     else if(e.y1 >= s[t<<1|1].lf) update(t<<1|1,e);//下传右儿子 
    58     else {//左右儿子都下传 
    59         k2 tmp = e;
    60         tmp.y2 = s[t<<1].rf;
    61         update(t<<1,tmp);
    62         tmp = e;
    63         tmp.y1 = s[t<<1|1].lf;
    64         update(t<<1|1,tmp);
    65     }
    66     calen(t);
    67 }
    68 
    69 int main() {
    70     int i,n,t,aa = 0;
    71     double x1,y1,x2,y2;
    72     while(scanf("%d",&n),n) {
    73         aa++;
    74         t = 1;
    75         for(int i = 1;i <= n; i++) {
    76             scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
    77             l[t].x = x1;
    78             l[t].y1 = y1;
    79             l[t].y2 = y2;
    80             l[t].f = 1;
    81             y[t++] = y1;
    82             l[t].x = x2;
    83             l[t].y1 = y1;
    84             l[t].y2 = y2;
    85             l[t].f = -1;
    86             y[t++] = y2;
    87         }
    88         sort(l+1,l+t,cmp);
    89         sort(y+1,y+t);
    90         build(1,1,t-1);//建树 
    91         update(1,l[1]);//下传lazy标记 
    92         double res = 0;
    93         for(int i = 2;i < t; i++) {
    94             res += s[1].cnt * (l[i].x - l[i-1].x);
    95             update(1,l[i]);
    96         }
    97         printf("Test case #%d
    Total explored area: %.2f
    
    ",aa,res);
    98     }
    99 }
  • 相关阅读:
    图解SQL的Join(转)
    MySQ数据表设计
    关于数据库DML、DDL、DCL区别
    SQL多表连接查询
    Xcode报错Expected selector for Objective-C and Expected method body
    Mac上安装使用MYSQL以及Navicat数据库管理和PHP服务器配置
    更换app开发者账号
    Mac 下的 C++ 开发环境
    spring-retry 重试机制
    Ribbon的主要组件与工作流程
  • 原文地址:https://www.cnblogs.com/lipeiyi520/p/10924620.html
Copyright © 2011-2022 走看看