USACO算法系列五——rect1

来源:互联网 发布:音频编辑软件破解版 编辑:程序博客网 时间:2024/05/22 10:23

    题目:http://www.nocow.cn/index.php/Translate:USACO/rect1

    最简单的想法是声明一个N*N的二维数组,用于表示单位1的矩形,二维数组的初始值为1,表示初始的颜色。一层一层的往上覆盖,不断更新数组的颜色值,最后统计一下二维数组里面各个颜色的个数就可以得出结果了。然而这种想法存在着严重的缺陷,第一时间,每次更新都需要更新A * B的空间,因此时间为o(N*A*B),加上最后统计,因此时间为o( A * B),因此最后的时间为O(N*A*B),A*B已经达到1亿次了,显然会超时。第二空间,按照题目的要求 1<= A,B<= 10000,因此最大的二维数组为一个亿的空间,即使是最短的short(因为颜色有2500种),空间超过要求了。

    为了节约空间,我想了一个方法是:一个单元最后的颜色取决于最后一个矩形在这个单元上的着色。即这个单元最后落在了哪个着色矩形当中,如果把着色的矩形倒过来考虑,那么就容易多了,就是这个单元最先出现在逆序的矩形单元当中。这样就可以不必存储一个10000 * 10000的二维数组了。遗憾的是,时间并没有得到缩减,遍历一个数组的时间是o(A*B),每次遍历必须考虑N个矩形,因此时间复杂度仍然是o(N*A*B)。

    怀着侥幸的心理,我还是将他实现了一下。代码如下:

     结果很显然,在TEST11的时候超时了。 

     接着昨天的内容,按单元扫描发现时间会超时,为了提速,想到了图形学里面的按行扫描填充多边形的算法。其实原理很相似,我们能不能逐行扫描,然后计算行通过矩形的长度呢?这样就可以一口气处理一行。同样的,我们将行跟逆序的矩形比较,如果这一行通过矩形,计算在通过矩形的长度,并将线段分成两段继续迭代到下一层矩形扫描。如此迭代,直到到达底层。剩下的线段就是底层的颜色长度了。代码如下:

 

    程序运行通过了,测试时间如下: