第十三届蓝桥杯大赛软件赛省赛(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=i1 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+fii,j,fi,j+fi,jj}+11i<i,1j<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+fii,j+1,fi,j+fi,jj+1}1,将 f i , 1 = i − 1 f_{i,1} = i-1 fi,1=i1 代入式中会发现,无论怎么拆分,最后表达式一定是若干 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×j1

  所以切分次数与切分方案无关,都是 i × j − 1 i × j - 1 i×j1

#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=a1a2+a1a3++a1an+a2a3++an2an1+an2an+an1an

【输入格式】

  输入的第一行包含一个整数 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 1n10001ai100
  对于所有评测用例, 1 ≤ n ≤ 200000 , 1 ≤ a i ≤ 1000 1 ≤ n ≤ 200000,1 ≤ a_i ≤ 1000 1n2000001ai1000


公式递推


  将 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)+a2a3++an2an1+an2an+an1an

  同样的将余项中包含 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)++an1an=a1i=2nai+a2i=3nai++an1i=nnai

  也就 S S S 等于每个元素乘以右边所有元素的和的和,考虑到实现计算的代码量,我们将 S S S 的项重排,重新整理出:

   S = a 1 ⋅ ∑ i = 1 0 a i + a 2 ⋅ ∑ i = 1 1 a i + ⋯ + a n ⋅

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值