蓝桥杯 2022年省赛真题
Java 大学A组
小做一会 J A \mathrm{JA} JA 打发时间。
试题 A: 裁纸刀
本题总分: 5 5 5 分
【问题描述】
小蓝有一个裁纸刀,每次可以将一张纸沿一条直线裁成两半。
小蓝用一张纸打印出两行三列共 6 6 6 个二维码,至少使用九次裁出来,下图给出了一种裁法。
在上面的例子中,小蓝的打印机没办法打印到边缘,所以边缘至少要裁 4 4 4 次。另外,小蓝每次只能裁一张纸,不能重叠或者拼起来裁。
如果小蓝要用一张纸打印出 20 20 20 行 22 22 22 列共 440 440 440 个二维码,他至少需要裁多少次?
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
443
我们可以仿照两行三列时,题目给出的切分法,写出一个递归程序去计算它的切割次数,
题目给出的方法可以抽象为两部分,
1 、 1、 1、边缘裁剪 4 4 4 次。
2 、 2、 2、选择当前纸片中连接二维码数量最多的一条线,沿其切割,分割成两个小纸片,重复此步直至纸片的某行或某列为 1 1 1。
public class Test {
public static void main(String[] args) {
System.out.println(calc(20, 22) + 4); }
static int calc(int row, int col) {
if (row > col) return calc(col, row);
if (col == 1) return row - 1;
if (row == 1) return col - 1;
if (row % 2 == 0) return 2 * calc(row / 2, col) + 1;
return calc(1, col) + 2 * calc(row / 2, col) + 2;
}
}
当然这种方式并非绝对最优,一种较为稳妥的方式是在记忆化处理下暴搜,不过总所周知,记忆化搜索是状压 d p \mathrm{dp} dp 的递归实现,由此,我们可以在状态转移方程上研究出最优方案之间的共性,
设状态 f i , j f_{i,j} fi,j 为 i i i 行 j j j 列的纸片在最优裁剪方案下的步骤数,显然有 f i , j = f j , i f_{i,j} = f_{j,i} fi,j=fj,i、 f i , 1 = i − 1 f_{i,1} = i-1 fi,1=i−1、 f i , j = min { f i ′ , j + f i − i ′ , j , f i , j ′ + f i , j − j ′ } + 1 ∣ 1 ≤ i ′ < i , 1 ≤ j ′ < j f_{i,j}=\min\{f_{i',j}+f_{i-i',j},f_{i,j'} +f_{i,j-j'}\}+1|1\leq i' < i,1\leq j' < j fi,j=min{ fi′,j+fi−i′,j,fi,j′+fi,j−j′}+1∣1≤i′<i,1≤j′<j,
当我们知道 f i ′ , j + f i − i ′ , j f_{i',j}+f_{i-i',j} fi′,j+fi−i′,j、 f i , j ′ + f i , j − j ′ f_{i,j'} +f_{i,j-j'} fi,j′+fi,j−j′ 中谁更优时,不妨假设当 i + j = k + g i+j=k+g i+j=k+g 时 f i , j = f k , g f_{i,j} = f_{k,g} fi,j=fk,g,
我们将 f i , j f_{i,j} fi,j 的表达式变形为 f i , j = min { f i ′ , j + f i − i ′ , j + 1 , f i , j ′ + f i , j − j ′ + 1 } − 1 f_{i,j}=\min\{f_{i',j}+f_{i-i',j}+1,f_{i,j'} +f_{i,j-j'}+1\}-1 fi,j=min{ fi′,j+fi−i′,j+1,fi,j′+fi,j−j′+1}−1,将 f i , 1 = i − 1 f_{i,1} = i-1 fi,1=i−1 代入式中会发现,无论怎么拆分,最后表达式一定是若干 f 1 , x + 1 f_{1,x}+1 f1,x+1、 f y , 1 + 1 f_{y,1}+1 fy,1+1 和 − 1 -1 −1 的累加,其和一定是 i × j − 1 i×j-1 i×j−1。
耶,我们证明切分次数与切分方案无关,
太棒了,草
试题 B: 寻找整数
本题总分: 5 5 5 分
【问题描述】
有一个不超过 1 0 17 10^{17} 1017 的正整数 n n n,知道这个数除以 2 2 2 至 49 49 49 后的余数如下表所示,求这个正整数最小是多少。
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
2022040920220409
扩展中国剩余定理
对于一元线性同余方程组 : : : { x ≡ r 1 ( m o d n 1 ) x ≡ r 2 ( m o d n 2 ) ⋮ x ≡ r k ( m o d n k ) \begin{cases} x &\equiv r_1 \pmod {n_1} \\ x &\equiv r_2 \pmod {n_2} \\ &\ \vdots \\ x &\equiv r_k \pmod {n_k} \\ \end{cases} ⎩⎪⎪⎪⎪⎨⎪⎪⎪⎪⎧xxx≡r1(modn1)≡r2(modn2) ⋮≡rk(modnk) 方程组的唯一是 x = ∑ i = 1 k r i m i i n v ( m i , n i ) ( m o d M ) x = \sum_{i=1}^kr_im_i\mathrm{inv}(m_i,n_i)\pmod M x=∑i=1krimiinv(mi,ni)(modM),其中 M = ∏ i = 1 k n 1 M = \prod_{i=1}^kn_1 M=∏i=1kn1, m i = M n i m_i = \frac{M}{n_i} mi=niM, i n v ( a , b ) \mathrm{inv}(a,b) inv(a,b) 为 a − 1 ( m o d b ) a^{-1}\pmod b a−1(modb)。
可是对于 gcd ( m i , n i ) ≠ 1 \gcd(m_i,n_i)\neq1 gcd(mi,ni)=1 的情况, i n v ( m i , n i ) \mathrm{inv}(m_i,n_i) inv(mi,ni) 不存在,此时无法使用 C R T \mathrm{CRT} CRT 求解。
于是引入扩展中国剩余定理 ( E X C R T ) : \mathrm{(EXCRT)}: (EXCRT):
对于 k = 2 k=2 k=2,即方程组为 : : : { x ≡ r 1 ( m o d n 1 ) x ≡ r 2 ( m o d n 2 ) \begin{cases}x&\equiv r_1 \pmod {n_1} \\ x &\equiv r_2 \pmod {n_2} \\ \end{cases} { xx≡r1(modn1)≡r2(modn2) 我们将 x x x 化为不定方程 x = n 1 p + r 1 = n 2 q + r 2 x=n_1p+r_1=n_2q+r_2 x=n1p+r1=n2q+r2,移项后有 n 1 p − n 2 q = r 2 − r 1 n_1p-n_2q=r_2-r_1 n1p−n2q=r2−r1,若 gcd ( n 1 , n 2 ) ∣ ( r 2 − r 1 ) \gcd(n_1,n_2)|(r_2-r_1) gcd(n1,n2)∣(r2−r1),另 k = n 1 gcd ( n 1 , n 2 ) k =\frac{n_1}{\gcd(n_1,n_2)} k=gcd(n1,n2)n1、 g = n 2 gcd ( n 1 , n 2 ) g =\frac{n_2}{\gcd(n_1,n_2)} g=gcd(n1,n2)n2,容易使用 E X G C D \mathrm{EXGCD} EXGCD 找到一组 p , q p,q p,q 使得 k p + q g = 1 kp+qg=1 kp+qg=1,此时 x ∗ = n 1 p + r 1 = r 2 − r 1 gcd ( n 1 , n 2 ) p + r 1 x^*=n_1p+r_1=\frac{r_2-r_1}{\gcd(n_1,n_2)}p+r_1 x∗=n1p+r1=gcd(n1,n2)r2−r1p+r1 同时满足两式。
当然题目中的方程数列为 48 48 48,我们需要将 x x x 推广到更一般的形式来计算出满足全部方程的 x x x,若 x x x 存在,容易对满足 x ≡ r 1 ( m o d n 1 ) x\equiv r_1 \pmod{n_1} x≡r1(modn1)、 x ≡ r 2 ( m o d n 2 ) x\equiv r_2 \pmod{n_2} x≡r2(modn2) 的特解 x ∗ = n 1 p + r 1 x^* = n_1p+r_1 x∗=n1p+r1 构造出平凡解系 x ∗ + k l c m ( n 1 , n 2 ) x^* + k\mathrm{lcm}(n_1,n_2) x∗+klcm(n1,n2),将两式化为一元线性同余方程 x ≡ x ∗ ( m o d l c m ( n 1 , n 2 ) ) x \equiv x^* \pmod{\mathrm{lcm}(n_1,n_2)} x≡x∗(modlcm(n1,n2))。
这个结论是显然的,但在此之上还有个推论就是一个完全剩余系中有且仅有一个解,
不想证,摆了。
不过这题用 J a v a \mathrm{Java} Java 实现起来较为恶心,因为 ( 1 , 49 ] (1,49] (1,49] 中的质数有 15 15 15 个,粗劣估计它们的乘积一定是会爆 long
,
叹息。
import java.math.BigInteger;
public class Test {
public static void main(String[] args) {
new Test().run(); }
int[] R = {
0, 0, 1, 2, 1, 4, 5, 4, 1, 2, 9, 0, 5, 10, 11, 14, 9, 0, 11, 18, 9, 11, 11, 15, 17, 9, 23, 20, 25, 16, 29, 27, 25, 11, 17, 4, 29, 22, 37, 23, 9, 1, 11, 11, 33, 29, 15, 5, 41, 46 };
void run() {
BigInteger M = BigInteger.valueOf(2), r = BigInteger.ONE;
for (int i = 3; i <= 49; ++i) {
BigInteger d = exgcd(M, BigInteger.valueOf(i));
exgcd(M.divide(d), BigInteger.valueOf(i).divide(d));
r = r.add(BigInteger.valueOf(R[i]).subtract(r).divide(d).multiply(p).multiply(M));
M = lcm(M, BigInteger.valueOf(i));
r = r.mod(M);
}
System.out.println(r);
}
BigInteger p, q;
BigInteger exgcd(BigInteger a, BigInteger b) {
if (b.equals(BigInteger.ZERO)) {
q = BigInteger.ZERO;
p = BigInteger.ONE;
return a;
}