• 倪文迪陪你学蓝桥杯2021寒假每日一题:1.12日(2017省赛A第10题)


    2021年寒假每日一题,2017~2019年的省赛真题。
    本文内容由倪文迪(华东理工大学计算机系软件192班)和罗勇军老师提供。

    后面的每日一题,每题发一个新博文,请大家看博客目录https://blog.csdn.net/weixin_43914593
    @

    2017省赛A类第10题,最后一题,题目链接:
    油漆面积 http://oj.ecustacm.cn/problem.php?id=1324

    1、题目描述


    平面上有n个矩形,给出每个矩形的坐标。这些矩形可能有重叠。
    问这些矩形覆盖的总面积是多少。
    数据规模:1<=n<10000,坐标0<= x1,y1,x2,y2 <=10000
    资源约定:内存 < 256M;CPU < 2000ms


    2、题解

      本题是一个经典问题:“矩形面积并”。
      首先给出两种暴力法。
      (1)先单独求每个矩形的面积,然后把所有矩形的面积加起来,最后减去任意两个矩形的交集。求矩形的交集很花时间,需要两两配对,复杂度(O(n^2))
      (2)另一种更简单的暴力法,是把平面划成单位边长为1(面积也是1)的方格。每读入一个矩形,就把它覆盖的方格标注为已覆盖;对所有矩形都这样处理,最后统计被覆盖的方格数量即可。编码极其简单,但是比上一种方法更慢,且消耗极大的空间。
      本题的数据非常弱:矩形数量少,坐标值也不大。用第(2)种暴力法,也能通过。对,就这么干!

    3、暴力

    #include<bits/stdc++.h>
    using namespace std;
    bool vis[10001][10001];   //100M内存
    
    int main(){
        int n,sum=0;   //sum:面积
        scanf("%d",&n);
        for(int k=0;k<n;k++){
            int x1,y1,x2,y2;
            scanf("%d%d%d%d",&x1,&y1,&x2,&y2);  //读一个矩形
            if(x1>x2)  swap(x1,x2);    //坐标排序
            if(y1>y2)  swap(y1,y2);
            for(int i=x1;i<x2;i++)     //统计这个矩形覆盖的面积
                for(int j=y1;j<y2;j++)
                    if(!vis[i][j]){    //没有被覆盖过
                        sum++;         //统计面积
                        vis[i][j]=1;   //标注为已经覆盖
                    }
        }
        cout<<sum;
        return 0;
    }
    

    3、标准解法

      当n很大,n<100000,且坐标值很大时,暴力法显然会超时。
      “矩形面积并”的标准解法是线段树的扫描线,建模和编码可不容易。参考博文“线段树”:
      https://blog.csdn.net/weixin_43914593/article/details/108221534
      其中的“7.1 矩形面积并”,和本题完全相同。

  • 相关阅读:
    Oracle学习
    挑战练习11.5 恢复CrimeFragment的边距
    844. Backspace String Compare
    496. Next Greater Element I
    682. Baseball Game
    707. Design Linked List
    挑战练习10.6 实现高效的RecyclerView刷新
    挑战练习9.5 日期格式化
    挑战练习8.8 RecyclerView ViewType
    挑战练习6.5 限制作弊次数
  • 原文地址:https://www.cnblogs.com/luoyj/p/14271432.html
Copyright © 2020-2023  润新知