【蓝桥杯】第十四届模拟赛第一期及第二期填空汇总
- 软件开发
- 2025-08-21 09:24:02

目录
1.A题(进制位数)
位运算符
第一期
问题描述
解析
第二期
解析
代码
2.B题(日期问题)
第一期
问题描述
解析
代码实现
执行结果
第二期
问题描述
解析
3.C题(数学问题)
第一期
问题描述
解析
代码实现
执行结果
第二期
问题描述
解析
4.D题(矩阵问题)
第一期
问题描述
解析
代码实现
第二期
问题描述
解析
5.E题(拆分问题)
第一期
问题描述
解析
第二期
问题描述
解析
总结
1.A题(进制位数) 位运算符 符号描述运算规则&与两个位都为1时,结果才为1|或两个位都为0时,结果才为0^异或两个位相同为1,相异为0~取反0变1,1变0<<左移各二进位全部左移若干位,高位丢弃,低位补0>>右移各二进位全部右移若干位,对无符号数,高位补0,有符号数,各编译器处理方法不一样,有的补符号位(算术右移),有的补0(逻辑右移) 第一期 问题描述
十进制整数 2 在十进制中是 1 位数,在二进制中对应 10 ,是 2 位数。
十进制整数 22 在十进制中是 2 位数,在二进制中对应 10110 ,是 5 位数。
请问十进制整数 2022 在二进制中是几位数?
解析根据常识2^10为1024,那么2^11就是2048,2048>2022,即2^10<2022<2^11。
由2<3<2^2,为两位数;2^4<22<2^5,为五位数可知2022的位数为10+1即11位。
答案:11位。
第二期请找到一个大于 2022 的最小数,这个数转换成二进制之后,最低的 6 个二进制为全为 0 。 请将这个数的十进制形式作为答案提交。
解析2022联想到2048(100000000000),for循环从2023开始,找到那个大于 2022 的最小数结束,判断方法:对该整数进行六次右移如果每一次的&(与)1都不为1,即最低的 6 个二进制为全为 0,那么这个数就是那个大于 2022 的最小数。
答案:2048。
代码 #include <bits/stdc++.h> using namespace std; int main() { int s; for (int i = 2023;; i++) { bool flag = false; for (int k = 0; k < 6; k++) { if (i >> k & 1) { flag = true; continue; } } if (!flag) { s = i; break; } } cout << s << endl; return 0; 2.B题(日期问题) 第一期 问题描述小蓝每周六、周日都晨跑,每月的 1、11、21、31 日也晨跑。其它时间不晨跑。
已知 2022 年 1 月 1 日是周六,请问小蓝整个 2022 年晨跑多少天?
解析由题意可知小蓝周末跑,日期位数为1的时候也跑。假设定义x为365天的某一天,那么小蓝周末跑的条件就是x%7==1为周六或x%7==1为周日,定义一个数组,每个元素代表着每个月份的日期,用枚举法判断日期是否为1、11、21、31 ,用count计算晨跑的天数,x随着循环加1,满足x%7==1或x%7==1或判断日期是否为1、11、21、31之一,count加1。
答案:138。
代码实现 #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { int x = 0, count = 0; int month[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; for (int i = 1; i < 13; i++) { for (int j = 1; j <= month[i]; j++) { x++; if (x % 7 == 1 || x % 7 == 2 || j == 1 || j == 11 || j == 21 || j == 31) { count++; } } } printf("%d", count); }虽然月份是12个,但是数组定义为13个,把第一个赋值为0,使用时从第二个元素开始,也就是下标为1代表着一月,这样便于理解
执行结果 第二期 问题描述我们计从 1949 年 10 月 1 日至 1949 年 10 月 2 日为经过了 1 天。请问从 1949 年 10 月 1 日至 2022 年 1 月 1 日经过了多少天?
解析分两段算,先计算1949 年 10 月 1 日到1950 年 1 月 1 日为31+30+31=92,在计算1950 年 1 月 1 日到2022 年 1 月 1 日,用for循环,判断是否为闰年,如果为闰年加366,不是闰年加365。最后两者相加即为答案。
答案:26390
代码
#include "stdio.h" int main() { int sum = 92; for (int i = 1950; i < 2022; i++) { if (i % 4 == 0 && i % 100 != 0 || i % 400 == 0) { sum += 366; } else { sum += 365; } } printf("%d", sum); return 0; } 3.C题(数学问题) 第一期 问题描述小蓝特别喜欢调和级数 S(n)=1/1+1/2+1/3+...+1/n
请问,n 至少为多大时,S(n)>12 ?
解析直接暴力累加计算,需要注意的是结果涉及到了循环的++运算
S>0 n=1S>1 n=2S>2 n=4S>3 n=11S>4 n=31S>5 n=83S>6 n=227S>7 n=616S>8 n=1674S>9 n=4550S>10 n=12367S>11 n=33617S>12 n=91380答案:91380
代码实现 #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { double sum = 0; int i; for (i = 1; sum <= 12; i++) { sum += 1.0 / i; } printf("%d", i - 1); return 0; }切记,切记,切记,最后输出n的时候要减1,因为在最后一次循环的结尾i又加1,而不满足条件的是i加1之前的值
执行结果 第二期 问题描述8518 是一个非常特殊的数,如果把这个数看成 16 进制数,它的值为 (8518)16=8*16*16*16+5*16*16+1*16+8=34072,而 34072 正好是 8518 的整数倍。9558 也是这样一个数,当看成 16 进制时是 38232。其实长度为 1 的数 0 到 9 都满足看成 16 进制后是自己的整数倍(1倍)。请问,除开长度为 1 的数,最小的满足这样条件的数是多少?
解析for循环从10开始往后枚举,直到找到满足条件的数结束,判断方法:现将该数转换为十六进制(对其求余每次除10从尾数求其位数,权重每循环一次乘以16,位数乘权重累加),最后在用这个数求余它本身10进制的数,如果为0,这满足,反之,继续循环。
答案:1038
代码
#include <bits/stdc++.h> using namespace std; int main() { int res; for (int i = 10;; i++) { int weight = 1; int ans = 0, sum = 0; int temp = i; while (temp) { sum = temp % 10; ans += sum * weight; weight *= 16; temp /= 10; } if (ans % i == 0) { res = i; break; } } cout << res << endl; return 0; } 4.D题(矩阵问题) 第一期 问题描述给定一个字母矩阵,如果矩阵中的某个位置不在四条边上,而且该位置上的字母小于其上下左右四个位置的字母,则称为一个山谷。
例如,对于如下矩阵
DDDDD
CADCE
FFFFA
共有两个山谷,位于第二行第二列和第四列。请注意第二行第三列和第三行第五列都不是山谷。
对于如下 3030 行 6060 列的字母矩阵,请问有多少个山谷?
PHQGHUMEAYLNLFDXFIRCVSCXGGBWKFNQDUXWFNFOZVSRTKJPREPGGXRPNRVY STMWCYSYYCQPEVIKEFFMZNIMKKASVWSRENZKYCXFXTLSGYPSFADPOOEFXZBC OEJUVPVABOYGPOEYLFPBNPLJVRVIPYAMYEHWQNQRQPMXUJJLOOVAOWUXWHMS NCBXCOKSFZKVATXDKNLYJYHFIXJSWNKKUFNUXXZRZBMNMGQOOKETLYHNKOAU GZQRCDDIUTEIOJWAYYZPVSCMPSAJLFVGUBFAAOVLZYLNTRKDCPWSRTESJWHD IZCOBZCNFWLQIJTVDWVXHRCBLDVGYLWGBUSBMBORXTLHCSMPXOHGMGNKEUFD XOTOGBGXPEYANFETCUKEPZSHKLJUGGGEKJDQZJENPEVQGXIEPJSRDZJAZUJL LCHHBFQMKIMWZOBIWYBXDUUNFSKSRSRTEKMQDCYZJEEUHMSRQCOZIJIPFION EEDDPSZRNAVYMMTATBDZQSOEMUVNPPPSUACBAZUXMHECTHLEGRPUNKDMBPPW EQTGJOPARMOWZDQYOXYTJBBHAWDYDCPRJBXPHOOHPKWQYUHRQZHNBNFUVQNQ QLRZJPXIOGVLIEXDZUZOSRKRUSVOJBRZMWZPOWKJILEFRAAMDIGPNPUUHGXP QNJWJMWAXXMNSNHHLQQRZUDLTFZOTCJTNZXUGLSDSMZCNOCKVFAJFRMXOTHO WKBJZWUCWLJFRIMPMYHCHZRIWKBARXBGFCBCEYHJUGIXWTBVTREHBBCPXIFB XVFBCGKCFQCKCOTZGKUBMJRMBSZTSSHFROEFWSJRXJHGUZYUPZWWEIQURPIX IQFLDUUVEOOWQCUDHNEFNJHAIMUCZFSKUIDUBURISWTBRECUYKABFCVKDZEZ TOIDUKUHJZEFCZZZBFKQDPQZIKFOBUCDHTHXDJGKJELRLPAXAMCEROSWITDP TPCCLIFKELJYTIHRCQAYBNEFXNXVGZEDYYHNGYCDRUDMPHMECKOTRWOSPOFG HFOZQVLQFXWWKMFXDYYGMDCASZSGOVSODKJGHCWMBMXRMHUYFYQGAJQKCKLZ NAYXQKQOYZWMYUBZAZCPKHKTKYDZIVCUYPURFMBISGEKYRGZVXDHPOAMVAFY RARXSVKHTQDIHERSIGBHZJZUJXMMYSPNARAEWKEGJCCVHHRJVBJTSQDJOOTG PKNFPFYCGFIEOWQRWWWPZSQMETOGEPSPXNVJIUPALYYNMKMNUVKLHSECDWRA CGFMZKGIPDFODKJMJQWIQPUOQHIMVFVUZWYVIJGFULLKJDUHSJAFBTLKMFQR MYJFJNHHSSQCTYDTEAMDCJBPRHTNEGYIWXGCJWLGRSMEAEARWTVJSJBAOIOJ LWHYPNVRUIHOSWKIFYGTYDHACWYHSGEWZMTGONZLTJHGAUHNIHREQGJFWKJS MTPJHAEFQZAAULDRCHJCCDYRFVVRIVUYEEGFIVDRCYGURQDREDAKUBNFGUPR OQYLOBCWQXKZMAUSJGMHCMHGDNMPHNQKAMHURKTRFFACLVGRZKKLDACLLTEO JOMONXRQYJZGINRNNZWACXXAEDRWUDXZRFUSEWJTBOXVYNFHKSTCENAUMNDD XFDMVZCAUTDCCKXAAYDZSXTTOBBGQNGVVPJGOJOGLMKXGBFCPYPCKQCHBDDZ WRXBZMQRLXVOBTWHXGINFGFRCCLMZNMJUGWWBSQFCIHUBSJOLLMSQSGHMCPH ELSOTFLBGSFNPCUZSRUPCHYNVZHCPQUGRIWNIQXDFJPWPXFBLKPNPEELFJMT
解析枚举法判断每个字符与该字符上下左右四个位置的字母的大小,如果该位置上的字母小于其上下左右四个位置的字母那么计数变量count++。
答案:276
代码实现 #include <iostream> using namespace std; int main() { char str[30][60]; int count = 0; for (int i = 0; i < 30; i++) { for (int j = 0; j < 60; j++) { // scanf("%c", &str[i][j]); cin >> str[i][j]; } } printf("\n"); for (int i = 0; i < 30; i++) { for (int j = 0; j < 60; j++) { printf("%c", str[i][j]); } } for (int i = 1; i < 29; i++) { for (int j = 1; j < 59; j++) { if (str[i - 1][j] > str[i][j] && str[i + 1][j] > str[i][j] && str[i][j - 1] > str[i][j] && str[i][j + 1] > str[i][j]) { count++; } } } printf("%d", count); return 0; }输入流cin无论什么情况下都会忽略tab、空格、回车等分隔符
scanf函数在除scanf("%c",&char)之外的所有情况都不会把回车符作为输入字符在输入缓存中读取,但scanf("%c",&char)也不会读取tab、空格,而是把他们作为分隔符在输入缓存中忽略。
第二期 问题描述小蓝有一个 30 行 60 列的数字矩阵,矩阵中的每个数都是 0 到 9 之间的数字。现在小蓝想从这个矩阵的第一行第一列画一条折线到第 30 行 60 列,线只能沿水平向右走或竖直向下走,只能在有数字的地方拐弯。小蓝想知道,这样一条线经过的数字的和最大是多少。
174094882455171152761423221685761892795431233411387427793198 650286024865090061389344606618496378829135984076361542097372 601657541200146071777733599818266038012509478351201640618984 143988087783837107349651099683484992553337438088068198972282 890781586124258626539246182119762952003918195325258677229419 698255491250839396799769357665825441616335532825361862146291 503649293440596342887581257444442930778730382520372975343211 325351222640703400531067500454956482168314849207060705673849 265774579830223671554026061117300483012903885770893074783710 083450145620356667677191627276513995926532444279237315785832 411595106453089134746365281031552217482363035280722591085079 053410485925413958279617719034175332412908745680774313630190 429314820559328748143552689295945058801322270313370955837837 939182801848609300876356583948397645861551964542532682663945 625356614462682551015176002433628234343684739800880514363921 982340231989891351425389287014819359798014755509282450440511 590838726938103384801541373585690893606978941566666714061214 952341523168827712604946036245881214982452998386986623826275 782780208928205527678781609589000725521486468983551558405472 149903035076783644195574734088152324666290493119955560594634 905391288186024902215444250421277955403412298227858394469856 607272647132163832860126054679347881638761723785858733108109 249157334220127702410373959720286708183036202841837581704881 367895556630088230650972282944827258473951902831431040790814 079538232104075905120989173307660289899942087873076421916033 622143260549608274076012938515668898707915863945382394851328 164677964192631597026176253407553188801750590935427267220117 591817866992665840378311257621611574856498432538327068011953 631534031790352912617015229051836886166704989498756486878095 690013558017746707412183571476823027885971347137127534455141
解析线性DP,状态计算为:f[i,j]=max(max(f[i - 1][j], f[i][j - 1])) + v,v是该点的权值。答案为f[30][60]。
答案:597
代码
#include <bits/stdc++.h> using namespace std; const int N = 35, M = 65; int f[N][M]; char s[N][M]; int main() { for (int i = 1; i <= 30; i++) scanf("%s", s[i] + 1); for (int i = 1; i <= 30; i++) for (int j = 1; j <= 60; j++) f[i][j] = max(f[i - 1][j], f[i][j - 1]) + s[i][j] - '0'; cout << f[30][60] << endl; return 0; } 5.E题(拆分问题) 第一期 问题描述小蓝有一个 100 行 100 列的矩阵,矩阵的左上角为 1。其它每个位置正好比其左边的数大 2,比其上边的数大 1 。
例如,第 1 行第 2 列为 3,第 2 行第 2 列 为 4,第 10 行第 20 列为 48。
小蓝想在矩阵中找到一个由连续的若干行、连续的若干列组成的子矩阵,使得其和为 2022,请问这个子矩阵中至少包含多少个元素(即子矩阵的行数和列数的乘积)。
解析首先我们要构造出这个矩阵, 假设这个矩阵为 a[ ][ ]。
矩阵的左上角为 1, 那么 a[1][1] = 1。其它每个位置正好比其左边的数大 2,我们可以构造出第一行 a[1][i] = a[1][i - 1] + 2其它每个位置正好比其上面的数大 1,根据第一行可以构造出其他 9行 a[i][j] = a[i - 1][j - 1] + 1我们要求一个子矩阵的和,考虑到矩阵长宽只有 100,我们可以通过枚举子矩阵的左上角 (i, j)以及右下角 (k, l),我们用最简单的四重循环来枚举,此时枚举的复杂度为O(n^4), 若此时和为 2022 矩阵的元素个数等于行数和列数的乘积,即(k−i+1)×(l−j+1), 对所有枚举结果取最小值。
查询子矩阵的和是否为 2022我们可以通过预处理二维前缀和O(1)查询。
答案:12
代码
#include<bits/stdc++.h> using namespace std; int a[150][150] , sum[150][150]; int cal(int x1, int y1, int x2, int y2){ return sum[x2][y2] - sum[x2][y1 - 1] - sum[x1 - 1][y2] + sum[x1 - 1][y1 - 1]; } signed main() { a[1][1] = 1; for(int i = 2;i <= 100;i++) a[1][i] = a[1][i - 1] + 2; for(int i = 2;i <= 100;i++) for(int j = 1;j <= 100;j++) a[i][j] = a[i - 1][j] + 1; for(int i = 1;i <= 100;i++){ for(int j = 1;j <= 100;j++) sum[i][j] = sum[i][j - 1] + a[i][j]; for(int j = 1;j <= 100;j++) sum[i][j] += sum[i - 1][j]; } int ans = 100 * 100; for(int i = 1;i <= 100;i++) for(int j = 1;j <= 100;j++) for(int k = i;k <= 100;k++) for(int l = j;l <= 100;l++) if(cal(i, j, k, l) == 2022) ans = min(ans,(k - i + 1) * (l - j + 1)); cout << ans << '\n'; return 0; } 第二期 问题描述将 2022 拆分成不同的质数的和,请问最多拆分成几个?
解析求出2~2022的质数,把它看成一个0-1背包问题的话,每一个质数看做一个物品,质数的大小为物品质量,重质量不超出2022,最多能装多少个质数。
答案:33
代码
#include <bits/stdc++.h> using namespace std; const int N = 2030; int f[N][N]; int primes[N];//2~2022的质数 int n; int cnt = 1;//质数的个数 bool isprime(int n) { for (int i = 2; i <= n / i; i++) if (n % i == 0) return false; return true; }//判断是否为质数(素数) int main() { for (int i = 2; i <= 2022; i++) if (isprime(i)) primes[cnt++] = i; for (int i = 1; i < cnt; i++) for (int j = 2; j <= 2022; j++) { if (primes[i] > j) f[i][j] = f[i - 1][j]; else f[i][j] = max(f[i - 1][j], f[i - 1][j - primes[i]] + 1); } cout << f[cnt - 1][2022] << endl; return 0; } 总结多练习进制问题、日期问题(围绕2022~2023)、数学问题、矩阵问题、拆分问题,
熟练掌握枚举、动态规划、0-1背包问题等等。
👍+✏️+⭐️是对博主最大的鼓励与支持!!!
【蓝桥杯】第十四届模拟赛第一期及第二期填空汇总由讯客互联软件开发栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“【蓝桥杯】第十四届模拟赛第一期及第二期填空汇总”
下一篇
C语言刷题(2)