3.13的cfdiv2
B.Madoka and the Elegant Gift
给定n*m的矩阵,矩阵中仅含0、1,求是否存在两个极大的、仅由1组成的子矩阵相交(若子矩阵扩张后无法满足都由1组成,则称其为极大矩阵)(若两个矩阵存在重叠部分,则称其相交)
题解:
1.我的思路,简单想一下有相交矩阵的情况,一行一行看的话,就相当于上下两行的极大行起始点不重合且有相交,故对每一行连通行的起始坐标后,再遍历每一行,进行比较,时间复杂度大概是O(n*m+n*m*m),这题数据比较小,给我暴力过了
(反思一下,循环里变量名都能写错,de了半天bug,麻)
1 |
|
2.正解思路:同样思考下出现极大块相交的情况,易知一定会形成凸型,且若形成凸型则必定形成极大块相交情况,故我们统计是否出现凸型
1 |
|
C.Madoka and Childish Pranks
题面:给定一个n*m的矩阵,初始时都为0,每次操作可以选定一块矩形区域,将该区域涂成象棋棋盘的样式(即左上角为0,上下左右01交替),给定最终的图案,求操作序列
PS:不要求最少次数、每次操作要求左上角坐标与右下角左标)
题解:
简单的bfs,和之前的油画思路一样,倒着涂就好,即涂完之后标记一个万能色,而操作简化成两种,要么划一个1X2的矩阵,要么划一个2X1的矩阵,每次操作后将万能色的坐标压入)
我一开始题意理解错了,以为棋盘的左上角原本就要是0才能涂,wa了好几发。。
1 |
|
代码可以简化,如果(1,1)是黑色直接printf(“-1”),然后每次只压入万能色或白色就好
其实都用不上bfs,直接遍历就好了,写bfs反而麻烦了。。
PS:看了一个红名大佬的码,初始状态都为0,他从下到上,从右往左涂,如果当前格为0,直接输出两边当前格坐标(强制当前格为白),若当前格为1,若行数>1,则向上涂,否则向左涂,保证当前步影响会被下一步覆盖,易知操作数一定为n*m-1,(1,1)不用涂,开vector存储答案都省了。。
D.Madoka and the Best School in Russia
题面:给定x、d,将x分解成几个数的乘积(这几个数都满足是d的倍数而不是d平方的倍数),分解方法超过2,则printYES,否则printNO
题解:
1.我们只需要知道分解方法是否超过2,显然,可以将x=q*d的p次方,则q一定不为d的倍数,若p≥2,我们一定能将x分解成x=(q*d)*d…..
即我们已经得到了一种分解方式
若p==0,则无解
若p==1,则无解
故我们继续讨论p≥2的情况
1.若q可以分解成两个数(≠1、q)的乘积(即q非质数),则我们可以将q=x*y,x、y一定不为d的倍数(若是,则q也是),得到一种新的分解方式,YES
2.若q为质数,则q无法继续分解,若d为质数,则NO。
3.是否有可能减少分解数的个数来得到新的解?若p==2,则不行,NO。否则将d分解成a*b,即d非质数,若p≥4,则x=(a*d)*(b*d)*(q*d),为什么a、b不能*q?—怕凑出q==b,a*q==d,即q是d的因子的情况,总之,若p≥4,则直接YES
3.若p==3,则分解出的a、b必须给q*d一个,即x=(a*d)*(q*b*d),我们需要求证,d是否存在一个因子,满足q*b不为d的倍数,若存在,则YES,若不存在,则NO
易知q为质数,d不为质数,若d与q互质,则YES
若d与q不互质,且q是质数,则d是q的倍数,d=n*q,若n≠q,则x=(q*q*d)*(n*d),即d不为q的平方时,YES
若n==q,则d=q*q,d分配时会出现d平方,NO
难点在于p==3时的分析,以及互质、质数的关系的运用
1 |
|
要注意1也算质数,return 1
2.官方题解:dp做法,我们先找到x所有满足是d的倍数而不是d平方倍数的因子,规定dp[i]为将x分解成i的方法数,易知dp[i]+=dp[i*k](k为x的因子),而该转移方程没法保证不重复,如2可分解成1、1、2或2、1、1,故我们规定除的数必须大于等于(初始为1,故大于等于)前一次除的数,故添加一维表示当前除的数
1 |
|
注意用map来实现dp