zoukankan      html  css  js  c++  java
  • Codeforces 963C Cutting Rectangle【口头AC】


    本蒟蒻没看出来这道题考什么,感觉就是看清这道题本质后进行模拟就可以了。没有写代码AC是因为模拟过程很难受。。非常感谢一位偶遇的学长给我的耐心讲解。。代码部分纯属yy,不保证正确性。。

    首先对于这题题意的理解,它不是说给你一堆小矩形让你拼成一个大矩形;而是给你一个大矩形让一个中二少年随便切看能不能切出来input给你的那些矩形。这两者的区别在于前者不需要保证刀痕对齐,而后者需要保证。

    这个刀痕就是突破口,我们想象一下由许多小矩形拼出来的大矩形是什么样子的。大矩形里有p+1个横条,我们单看一个横条注意到这个横条里的小矩形都是高度固定,长度可能一样可能不一样的。(为什么这样呢,因为横着切的刀痕要平整,所以高度必须一样不能突出来一块)

    这时候我们想到要给每个高度维护一个单位矩阵。我们再想象一下把所有高度相同的小矩形拿出来横着拼在一起,那么这个拼在一块的矩形可能是h*(2x+4y+10z) [x,y,z均是小矩形的长度]。那这样的话单位矩阵就是h*(x+2y+5z)。这个时候想一下单位矩阵的本质,它的本质是你对这个拼接后的矩形最多竖切了多少刀后得到的矩形。(我们发现x,y,z前常数的公因数可能有很多(意味着有很多种切法),但我们明白最大公因数是能切的最多刀数【如果比gcd还大那满足不了竖着切刀痕对齐】)单位矩阵的优越性后面会讲到。

    这时我们维护一个a数组其中a[h][i]表示高度为h的单位矩阵中长度为i的小矩形有多少个。(离散化数组就开的下了)拿原来每个【高度相同但长度不同】小矩形的数量除以最大刀数可以得到。这时我们把所有不同高度的单位矩阵都维护出来。我们发现两个单位矩阵之间,如果他们高度相同那一定可以上下接和左右接拼成更大的矩形;但如果高度不同那他可能能上下接,一定不能左右接(因为要保证横着切的刀痕对齐)。

    什么情况下不能上下接呢,就是a[h][i]里的数值不一致时。即单位矩阵的宽度构成不一样,因为不一样的话就保证不了竖着切刀痕对齐了,这种情况下输出0。

    这时我们维护一个b数组,b[h]表示高度为h的单位矩阵有多少个,由count[h](高度为h的小矩形数量)除以 ∑(a[h][i])做一个单位矩阵要耗费的矩形数量)。这个时候单位矩阵的优越性就体现出来了,因为大矩阵实际上由若干个不同的单位矩阵构成,或者说不维护单位矩阵的话就不可做。首先最保守的方法是一行摆一个单位矩阵,那这一定是一组解;如果每个b[h]都是2的倍数的话,那每一行摆两个相同的单位矩阵也是一组解(不同的单位矩阵间不能左右连接)。注意到解的数量就是b[h]们公因数的数量。这个时候穷搜的话会超时,所以我们优化一下先求出最大公因数再求gcd因数的数量就是答案。(整除gcd的一定是cd,能整除b[h]们的一定也能整除他们的gcd,因为gcd是线性组合)

    以上。

  • 相关阅读:
    2006百度之星
    使用StretchBlt之前一定要用SetStretchBltMode(COLORONCOLOR)
    算法学习建议(转)
    让ARM开发板上SD卡里的程序开机自动运行
    我的Dll(动态链接库)学习笔记
    WinCE 应用程序开机自动运行的又一种方法
    讲讲volatile的作用
    用Platform builder定制WinCE系统
    MFC如何高效的绘图
    利用c语言编制cgi实现搜索
  • 原文地址:https://www.cnblogs.com/ZhenghangHu/p/8978623.html
Copyright © 2011-2022 走看看