蓝桥杯 2022年省赛真题
C/C++ 大学A组
One more time, One more chance - Uru ♪
试题 A: 裁纸刀
本题总分: 5 5 5 分
【问题描述】
小蓝有一个裁纸刀,每次可以将一张纸沿一条直线裁成两半。
小蓝用一张纸打印出两行三列共 6 6 6 个二维码,至少使用九次裁出来,下图给出了一种裁法。
在上面的例子中,小蓝的打印机没办法打印到边缘,所以边缘至少要裁 4 4 4 次。另外,小蓝每次只能裁一张纸,不能重叠或者拼起来裁。
如果小蓝要用一张纸打印出 20 20 20 行 22 22 22 列共 440 440 440 个二维码,他至少需要裁多少次?
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
443
设状态 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,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。
所以切分次数与切分方案无关,都是 i × j − 1 i × j - 1 i×j−1。
#include <stdio.h>
int n = 20, m = 22;
int main() {
printf("%d", n * m + 3);
}
试题 B: 灭鼠先锋
本题总分: 5 5 5 分
【问题描述】
灭鼠先锋是一个老少咸宜的棋盘小游戏,由两人参与,轮流操作。
灭鼠先锋的棋盘有各种规格,本题中游戏在两行四列的棋盘上进行。游戏的规则为:两人轮流操作,每次可选择在棋盘的一个空位上放置一个棋子,或在同一行的连续两个空位上各放置一个棋子,放下棋子后使棋盘放满的一方输掉游戏。
小蓝和小乔一起玩游戏,小蓝先手,小乔后手。小蓝可以放置棋子的方法很多,通过旋转和翻转可以对应如下四种情况 : : :
X O O O \mathrm{XOOO} XOOO X X O O \mathrm{XXOO} XXOO O X O O \mathrm{OXOO} OXOO O X X O \mathrm{OXXO} OXXO
O O O O \mathrm{OOOO} OOOO O O O O \mathrm{OOOO} OOOO O O O O \mathrm{OOOO} OOOO O O O O \mathrm{OOOO} OOOO
其中 O \mathrm O O 表示棋盘上的一个方格为空, X \mathrm X X 表示该方格已经放置了棋子。
请问,对于以上四种情况,如果小蓝和小乔都是按照对自己最优的策略来玩游戏,小蓝是否能获胜。如果获胜,请用 V \mathrm V V 表示,否则用 L \mathrm L L 表示。请将四种情况的胜负结果按顺序连接在一起提交。
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个长度为 4 4 4 的由大写字母 V \mathrm V V 和 L \mathrm L L 组成的字符串,如 V V L L \mathrm{VVLL} VVLL,在提交答案时只填写这个字符串,填写多余的内容将无法得分。
VVVL
SG 函数
标题应该起博弈论的,但我代码都写完了就懒得改了。
根据公平组合游戏定理有 : : :
1 ) : 1): 1):没有后继状态的状态是必败状态。
2 ) : 2): 2):一个状态是必胜状态,当且仅当存在至少一个必败状态为它的后继状态。
3 ) : 3): 3):一个状态是必败状态,当且仅当它的所有后继状态均为必胜状态。
显然棋盘被放满是一个必胜状态,以它作为递归函数出口,然后根据公平组合游戏定理递归就行。
#include <stdio.h>
int SG(int line1, int line2) {
if (line1 == 0b1111 && line2 == 0b1111) return 1;
if ((line1 & 0b1000) == 0)
if (!SG(line1 | 0b1000, line2)) return 1;
if ((line2 & 0b1000) == 0)
if (!SG(line1, line2 | 0b1000)) return 1;
for (int i = 0; i < 3; ++i) {
if ((line1 & (1 << i)) == 0)
if (!SG(line1 | (1 << i), line2)) return 1;
if ((line2 & (1 << i)) == 0)
if (!SG(line1, line2 | (1 << i))) return 1;
if ((line1 & (0b11 << i)) == 0)
if (!SG(line1 | (0b11 << i), line2)) return 1;
if ((line2 & (0b11 << i)) == 0)
if (!SG(line1, line2 | (0b11 << i))) return 1;
}
return 0;
}
int main() {
printf("%c", SG(0b1000, 0b0000) ? 'V' : 'L');
printf("%c", SG(0b1100, 0b0000) ? 'V' : 'L');
printf("%c", SG(0b0100, 0b0000) ? 'V' : 'L');
printf("%c", SG(0b0110, 0b0000) ? 'V' : 'L');
}
试题 C: 求和
时间限制: 1.0 s 1.0\mathrm s 1.0s 内存限制: 256.0 M B 256.0\mathrm{MB} 256.0MB 本题总分: 10 10 10 分
【问题描述】
给定 n n n 个整数 a 1 , a 2 , ⋯ , a n a_1, a_2, \cdots , a_n a1,a2,⋯,an,求它们两两相乘再相加的和,即 S = a 1 ⋅ a 2 + a 1 ⋅ a 3 + ⋯ + a 1 ⋅ a n + a 2 ⋅ a 3 + ⋯ + a n − 2 ⋅ a n − 1 + a n − 2 ⋅ a n + a n − 1 ⋅ a n 。 S = a_1\cdot a_2 + a_1\cdot a_3 + \cdots + a_1\cdot a_n + a_2\cdot a_3 +\cdots + a_{n−2}\cdot a_{n−1} + a_{n−2}\cdot a_n + a_{n−1}\cdot a_n。 S=a1⋅a2+a1⋅a3+⋯+a1⋅an+a2⋅a3+⋯+an−2⋅an−1+an−2⋅an+an−1⋅an。
【输入格式】
输入的第一行包含一个整数 n n n 。
第二行包含 n n n 个整数 a 1 , a 2 , ⋯ , a n a_1, a_2,\cdots,a_n a1,a2,⋯,an。
【输出格式】
输出一个整数 S S S,表示所求的和。请使用合适的数据类型进行运算。
【样例输入】
4
1 3 6 9
【样例输出】
117
【评测用例规模与约定】
对于 30 % 30\% 30% 的数据, 1 ≤ n ≤ 1000 , 1 ≤ a i ≤ 100 1 ≤ n ≤ 1000,1 ≤ a_i ≤ 100 1≤n≤1000,1≤ai≤100。
对于所有评测用例, 1 ≤ n ≤ 200000 , 1 ≤ a i ≤ 1000 1 ≤ n ≤ 200000,1 ≤ a_i ≤ 1000 1≤n≤200000,1≤ai≤1000。
公式递推
将 S S S 中包含 a 1 a_1 a1 的项整理出来,有:
S = a 1 ⋅ ( a 2 + a 3 + ⋯ + a n ) + a 2 ⋅ a 3 + ⋯ + a n − 2 ⋅ a n − 1 + a n − 2 ⋅ a n + a n − 1 ⋅ a n S=a_1\cdot(a_2+a_3+\cdots+a_n)+ a_2\cdot a_3 +\cdots + a_{n−2}\cdot a_{n−1} + a_{n−2}\cdot a_n + a_{n−1}\cdot a_n S=a1⋅(a2+a3+⋯+an)+a2⋅a3+⋯+an−2⋅an−1+an−2⋅an+an−1⋅an
同样的将余项中包含 a 2 a_2 a2、 a 3 a_3 a3、 ⋯ \cdots ⋯、 a n a_n an 的项整理出来:
S = a 1 ⋅ ( a 2 + a 3 + ⋯ + a n ) + a 2 ⋅ ( a 3 + a 4 + ⋯ + a n ) + ⋯ + a n − 1 ⋅ a n = a 1 ⋅ ∑ i = 2 n a i + a 2 ⋅ ∑ i = 3 n a i + ⋯ + a n − 1 ⋅ ∑ i = n n a i \begin{aligned}S&=a_1\cdot(a_2+a_3+\cdots+a_n)+ a_2\cdot(a_3+a_4+\cdots+a_n)+\cdots+a_{n-1}\cdot a_n\\&=a_1\cdot\sum_{i=2}^na_i+a_2\cdot \sum_{i=3}^na_i+\cdots+a_{n-1}\cdot\sum_{i=n}^{n}a_i\end{aligned} S=a1⋅(a2+a3+⋯+an)+a2⋅(a3+a4+⋯+an)+⋯+an−1⋅an=a1⋅i=2∑nai+a2⋅i=3∑nai+⋯+an−1⋅i=n∑nai
也就 S S S 等于每个元素乘以右边所有元素的和的和,考虑到实现计算的代码量,我们将 S S S 的项重排,重新整理出:
S = a 1 ⋅ ∑ i = 1 0 a i + a 2 ⋅ ∑ i = 1 1 a i + ⋯ + a n ⋅