离散-ACM一道强有力的工具

最近几天散搞哭了,都怪以前看到没好好学。。。

就拿一道题来说事PKU:1151,以前Matrix67写过这道题的BLOG,引用一下:

VOJ1056(http://www.vijos.cn/Problem_Show.asp?id=1056) 永远是离散化的经典问题。大意是给定平面上的n个矩形(坐标为整数,矩形与矩形之间可能有重叠的部分),求其覆盖的总面积。平常的想法就是开一个与二维坐标规模相当的二维Boolean数组模拟矩形的“覆盖”(把矩形所在的位置填上True)。可惜这个想法在这里有些问题,因为这个题目中坐标范围相当大(坐标范围为-10^8到10^8之间的整数)。但我们发现,矩形的数量n<=100远远小于坐标范围。每个矩形会在横纵坐标上各“使用”两个值, 100个矩形的坐标也不过用了-10^8到10^8之间的200个值。也就是说,实际有用的值其实只有这么几个。这些值将作为新的坐标值重新划分整个平面,省去中间的若干坐标值没有影响。我们可以将坐标范围“离散化”到1到200之间的数,于是一个200*200的二维数组就足够了。实现方法正如本文开头所说的“排序后处理”。对横坐标(或纵坐标)进行一次排序并映射为1到2n的整数,同时记录新坐标的每两个相邻坐标之间在离散化前实际的距离是多少。这道题同样有优化的余地。

我具体讲讲怎么优化:

当我们定义一个Boolean类型去解小范围的这道题是,假如是这样的图形:

哎呀,好挫的一张图。。(该学学绘图软件了)

坐标分别对应是:(0,0)-(2,2),(2,2)-(4,4);

当我们用Boolean枚举是,每次枚举一个小格子的左上角的状态代替这个单位面积;比如:

可以化成这样的左边矩阵:11000

11110

01110

01110

具体每个格子代表为1;但是程序怎么写,可以把每个格子的一个角的状态表示这个格子的状态,这样就OK了,我开始在这里纠结了老半天

但是这道题、N和M如此大,普通的标记肯定没戏,

SO ,离散:

神马是离散,就是把点的位子分别映射对应,

这里是:我们排序好,然后把这些点的位置分别映射其排序好的序号。(好像很绕口的样子) 23333;

等下在结合代码看看,

然后我们发现对应好一个新的图形出现了,

然后再用前面的方法去枚举标状态;

最后统计;

#include<iostream>
#include <algorithm>
#include<string.h>
#include<cstdio>
#include<math.h>
using namespace std;
double x[201],y[201],s[101][4];
int xy[201][201];
int n,cas=0;
double sum;
int main()
{
    int i,j,k;
    while(cin>>n)
    {
        if(n==0)   break;
        cas++;
        k=0;
        sum=0.0;
        memset(xy,0,sizeof(xy));

        for(i=1;i<=n;i++)
        {
            cin>>s[i][0]>>s[i][1]>>s[i][2]>>s[i][3];
            x[k]=s[i][0];
            y[k]=s[i][1];
            k++;
            x[k]=s[i][2];
            y[k]=s[i][3];
            k++;
        }
        sort(x,x+2*n);
        sort(y,y+2*n);

        for (int i=1;i<=n;i++)
        {
         int  i1=lower_bound(x,x+2*n,s[i][0])-x;//二分查找,跟普通的FOR语句一样
         int  j1=lower_bound(y,y+2*n,s[i][1])-y;
         int  i2=lower_bound(x,x+2*n,s[i][2])-x;
         int  j2=lower_bound(y,y+2*n,s[i][3])-y;
         for (int p1=i1;p1<i2;p1++)//标记状态,记住我们是以一个方块的角标记状态所以p1<i2,不是<=
         for (int p=j1;p<j2;p++)
         xy[p1][p]=1;
        }
        for (int i=0;i<2*n;i++)//统计
            for (int j=0;j<2*n;j++)
            if (xy[i][j]) {
            sum+=(x[i+1]-x[i])*(y[j+1]-y[j]);
        }
         printf("Test case #%d\n",cas);
         printf("Total explored area: %.2f\n",sum);
         printf("\n");
    }
    return 0;
}

最后还得贴代码,尼玛,我自己的看不懂怎么描述的?

还有跟我一样陷入离散杯具的孩子,欢迎留言,一起解决,^&&^^

离散-ACM一道强有力的工具,布布扣,bubuko.com

时间: 2024-10-13 11:41:42

离散-ACM一道强有力的工具的相关文章

Docker 网络之pipework 工具(2)将Docker容器配置到本地网络环境中

为了使本地网络中的机器和Docker容器更方便的通信,我们经常会有将Docker容器配置到和主机同一网段的需求.这个需求其实很容易实现,我们只要将Docker容器和主机的网卡桥接起来,再给Docker容器配上IP就可以了.下面我们来操作一下,我主机A地址为192.168.1.107/24,网关为192.168.1.1,需要给Docker容器的地址配置为192.168.1.150/24.在主机A上做如下操作:安装pipework下载地址:wgethttps://github.com/jpetazz

盘点最实用的大数据可视化分析工具(1/4)

俗话说的好:工欲善其事,必先利其器!一款好的工具可以让你事半功倍,尤其是在大数据时代,更需要强有力的工具通过使数据有意义的方式实现数据可视化,还有数据的可交互性:我们还需要跨学科的团队,而不是单个数据科学家.设计师或数据分析员:我们更需要重新思考我们所知道的数据可视化,图表和图形还只能在一个或两个维度上传递信息, 那么他们怎样才能与其他维度融合到一起深入挖掘大数据呢?此时就需要倚仗大数据可视化(BDV)工具,因此,笔者收集了适合各个平台各种行业的多个图表和报表工具,这些工具中不乏有适用于NET.

55个最实用的大数据可视化分析工具

俗话说的好:工欲善其事,必先利其器!一款好的工具可以让你事半功倍,尤其是在大数据时代,更需要强有力的工具通过使数据有意义的方式实现数据可视化,还有数据的可交互性:我们还需要跨学科的团队,而不是单个数据科学家.设计师或数据分析员:我们更需要重新思考我们所知道的数据可视化,图表和图形还只能在一个或两个维度上传递信息, 那么他们怎样才能与其他维度融合到一起深入挖掘大数据呢?此时就需要倚仗大数据可视化(BDV)工具,因此,笔者收集了适合各个平台各种行业的多个图表和报表工具,这些工具中不乏有适用于NET.

Java端ACM输入解析器(高效)

最近注册了一个codeforeces的帐号,想在那上面刷刷题目.但是发现它用的是控制台输入数据.因此为了能够接收到这些数据,就动手写了一个Acm的输入解析器. 先说说这个解析器的缺点: 这个解析器只能用于ascii码的输入,而由于acm一般为了照顾像c和c++这样的语言,都会选择使用ascii码作为输入,因此能完美符合这一限制. 代码比较长,总共有300行代码. 使用需要一定的缓存空间(约256字节) 再说说这个解析器的优点: 速度较Scanner快不少. 使用简单. 功能强大.(对于ACM来说

最实用的大数据可视化分析工具汇总(3/4)

一款好的工具可以让你事半功倍,尤其是在大数据时代,更需要强有力的工具通过使数据有意义的方式实现数据可视化.这些工具中不乏有适用于.NET.Java.Flash.HTML5.Flex等平台的,也不乏有适用于常规图表报表.甘特图.流程图.金融图表.工控图表.数据透视表.OLAP多维分析等图表报表开发的,下面就来看看全球备受欢迎的的可视化工具都有哪些吧! 二十九.Gantti Gantti是一个开源的PHP类,帮助用户即时生成Gantti图表.使用Gantti创建图表无需使用JavaScript,纯H

最实用的大数据可视化分析工具汇总(2/4)

一款好的工具可以让你事半功倍,尤其是在大数据时代,更需要强有力的工具通过使数据有意义的方式实现数据可视化.这些工具中不乏有适用于.NET.Java.Flash.HTML5.Flex等平台的,也不乏有适用于常规图表报表.甘特图.流程图.金融图表.工控图表.数据透视表.OLAP多维分析等图表报表开发的,下面就来看看全球备受欢迎的的可视化工具都有哪些吧! 十五.Kartograph Kartograph不需要任何地图提供者,如Google Maps,用来建立互动式地图,它由两个libraries组成,

让敏捷工具在敏捷开发中发挥高效作用

敏捷软件开发绝不再是一个新名词了,但理解还是时时有偏差.敏捷宣言中的第一条“个体和互动高于流程和工具”,有人就误读为“有了沟通,一切都迎刃而解” ,因此花费大量精力整顿团队合作,却轻视了工具(技术).其实宣言中的意思只是想强调个人和沟通更重要而已. 实际上,既然是软件开发,在所难免得面临工具的选择,而且很多优秀软件实践离开强有力的工具支持都玩不转.在如今的软件开发世界中,工具(这里谈的是软件工具)层出不穷,数不胜数,那么到底该怎么去选择适合的工具呢? 本文将根据我十几年的企业级软件开发经验给出一

人生最重要的几件事

时间是唯一的稀缺资源 先听一个故事:有一个国度,每个人早上醒来账户里都有86400元钱,然后每个人都必须花完,否则第二天零点账户自动清零,然后重新给你86400元钱,你会怎么做? 你可能会觉得很扯淡,但我们也是这样的,只不过给的不是现金,而是时间,我们每天都有86400秒,你会怎么做? 我很欣赏<木星上行>里面的一句台词: 只有时间在宇宙中才是最为宝贵的资源. 你所要做的是为自己的时间定一个价钱,比如300元/小时,当你意识到自己的时间究竟有多值钱时,你就不太可能再浪费时间了. 选择的力量 很

数据加密到底管不管用

数字世界中的加密就好比是现实世界中的保险箱.数据妥善保管起来,只有拥有相应密钥的那些人才能看见.数据加密为数据安全的机密性提供了一道强有力的保障;如今,加密在云计算领域正在迅速流行起来.但经过加密的数据就因而变得更安全吗?要是你的密钥以明文格式传输.被人复制或者管理不当,并非如此. 传输到公有云的数据通常安全地传输,文件并不保存在公共网站服务器上,所以明显的安全措施已经落实到位.可是一旦数据进入到存储服务器,数据就不在用户的触及或掌控范围之内.数据在存储时可能经过加密,也可能不是这样;这些数据可