
蓝桥杯 2023 年省赛 C++ 组 A 组填空题(幸运数与有奖问答)题解 + 锐评
A 题(幸运数):
答案:4430091
思路:只需要偶数位,那么就只枚举偶数位的数字,不管奇数位的数字,省时间。
但是直接枚举整个数字再分拆成两段显然常数有点大,所以我们可以分别枚举数字的前半段与后半段,分别判断数位和是否相等就会好做很多。
一亿之内的偶数位数字,有 1000 0000 ~ 9999 9999,10 0000 ~ 99 9999,1000 ~ 999,10 ~ 99 这几个范围。因为奇数位的没有被枚举,中间有空档,所以枚举的运算量不超过一亿。分拆数字的那一个 log 因为过小(最大也为 4),可以被丢掉。就算算上最大运算量也大约在一亿,轻松一秒之内跑过。
实际上不分类讨论,直接从 1 蛮到 1 0000 0000 也只需要 10 秒……出题人你在干什么,完全看不懂这道题想考察什么。
代码:
//
// main.cpp
// 幸运数
//
// Created by SkyWave Sun on 2023/4/8.
//
#include <iostream>
using namespace std;
int numSum(int num) {
int ans = 0;
while (num) {
ans += num % 10;
num /= 10;
}
return ans;
}
int main(int argc, const char * argv[]) {
int sum = 0;
for (int i = 1; i <= 9; ++i) {
for (int j = 0; j <= 9; ++j) {
if (numSum(i) == numSum(j)) {
++sum;
}
}
}
for (int i = 10; i <= 99; ++i) {
for (int j = 00; j <= 99; ++j) {
if (numSum(i) == numSum(j)) {
++sum;
}
}
}
for (int i = 100; i <= 999; ++i) {
for (int j = 000; j <= 999; ++j) {
if (numSum(i) == numSum(j)) {
++sum;
}
}
}
for (int i = 1000; i <= 9999; ++i) {
for (int j = 0000; j <= 9999; ++j) {
if (numSum(i) == numSum(j)) {
++sum;
}
}
}
printf("%d\n",sum);
return 0;
}
B 题(有奖问答):
答案:8335366
思路:背包典题,但是一看范围……怎么才 30,不爆搜都对不起出题人。
爆搜记录两个参数,当前做的是哪道题,当前分数是多少。每次有两种情况,对与不对。对的话就开始做下一道题,分数 + 10,否则也开始做下一道题,分数置 0。如果分数等于 70 的话就增加答案,注意这里不能回溯,因为还有可能达到 70,分数被置 0 后又达到 70了。如果分数达到 100 要根据题意直接回溯,如果题全部答完了也要进行回溯。
时间复杂度为 ,最大运算量为十亿,十秒搜出来。
代码:
//
// main.cpp
// 有奖问答
//
// Created by SkyWave Sun on 2023/4/8.
//
#include <iostream>
using namespace std;
int ans = 0;
void dfs(int pos, int sum) {
if (sum == 70) {
++ans;
}
if (sum == 100) {
return;
}
if (pos == 31) {
return;
}
dfs(pos + 1, sum + 10);
dfs(pos + 1, 0);
}
int main(int argc, const char * argv[]) {
dfs(1, 0);
printf("%d\n",ans);
return 0;
}
锐评:
首先作为场外选手,评价是题目质量比上一次比赛要好得多。没有像上次出现题面有争议、表述不清的情况,题目也稍有意思些,没有出现放了个题目不知道要考察啥的表现。
但——除了填空题。
这次的填空题是真的垃圾。首先 A 组和 B 组的填空题应该对调一下, B 组两道题目都比 A 组难。A 组居然考两道爆搜,不需要任何优化的那种,完全不知道在考察选手的啥,码力?还是 dfs 又没有学好?反观 B 组的两道题目,第一道题虽然是搜索,但好歹你没加剪枝,比赛结束跑不出来。第二道题同。反观 A 组,第一道题毫不剪枝,蛮力枚举也只需要 10 秒。第二道题更离谱,哪个人教你 dp 题的 n 开 30的???同样 10 秒跑出来。
唯一有一丁点思维含量的还是 B 组的第二道题目,没错,就一丁点。小学二年级奥数的思维。但这道题实在不适合出道填空题里面,因为这个信息熵根据自己的直觉都能知道答案的大致范围……首先信息熵和长度的一半非常相近,那么很多人就想到了从长度的一半往前枚举。然后发现一段时间搜不出来,再把这个枚举的起点往前移。说实话答案就离长度差六十万而已……人品好的肯定有试出来的。
就作为一个出题人,你做填空题你要做一定要用机器判断的。就像第一题一样,100 里挑 8 个数哪个人能在赛时完成?但是你出一个能用人类直觉观察出来的,合适吗?
所以总结:今年 C++ 组填空四道爆搜。蓝桥杯新增称号:爆搜杯。
更多推荐
所有评论(0)