2023第十四届蓝桥杯大赛软件赛国赛C/C++ 大学 B 组(真题&题解)(C++/Java题解)
本来想刷省赛题呢,结果一不小心刷成国赛了
真是个小迷糊〒▽〒
但,又如何( •̀ ω •́ )✧
记录刷题的过程、感悟、题解。
希望能帮到,那些与我一同前行的,来自远方的朋友😉
注:感谢@Witton的提示,题目部分已完成修改( •̀ ω •́ )y
大纲:
一、子2023-(题解)-递推or动态规划
二、双子数-(题解)-筛法、类型(unsigned long long)😥
三、班级活动-(题解)-不出所料、贪心+计数
四、合并数列-(题解)-妥妥的前缀和😥,当然双指针也能做
五、数三角-(题解)-这个真的就是算术题了,还要用到各种优化(叉乘、用半径分组)
六、删边问题-(题解)-图(tarjan算法)割边、割点,经典板子题
七、AB路线-(题解)-BFS广搜,最短路径、记忆话搜索😉
八、抓娃娃-(题解)-简单点的差分+前缀和😊
九、十,等后续冲击国赛时,再解决。
一、子2023
问题描述
小蓝在黑板上连续写下从 1 到 2023之间所有的整数,得到了一个数字序列: S=12345678910111213...20222023。 小蓝想知道 S 中有多少种子序列恰好等于 2023?
以下是 3 种满足条件的子序列(用中括号标识出的数字是子序列包含的数字):
1[2]34567891[0]111[2]1[3]14151617181920212223...
1[2]34567891[0]111[2]131415161718192021222[3]...
1[2]34567891[0]111213141516171819[2]021222[3]...
注意以下是不满足条件的子序列,虽然包含了 2、0、2、3 四个数字,但是顺序不对:
1[2]345678910111[2]131415161718192[0]21222[3]...
答案提交
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
动态规划解法:
本题解法,说成是状态规划,可能会引起恐惧,其实它就是一道简单的状态推导题( •̀ ω •́ )✧
C++
#include
#include
using namespace std;
// 是个简单的动态规划就算了
// 怎么又是一道越界题目
// 以后统一不用long long改用 unsigned long long。更大。
int main(){
vector dp(4,0);
string str="";
for(int i=1; i2) num1 += i-2; // 求取数量相同的数在减2;
else if(i==1) num2++;
}
int sum = 0;
// 当已被占用的id的数量,大于未被占用id时,那么sum = num1;
if(num1>num2){
sum = num1;
}else{ // num2>m;
vector a(n,0);
vector b(m,0);
for(int i=0; i>a[i];
for(int i=0; i>b[i];
// sum_a a数列的前缀和
// sum_b b数列的前缀和
// cnt_a a的位数
// cnt_b b的位数
// cnt_sum 总共需要的次数
long long sum_a=0,sum_b=0,cnt_a=0,cnt_b=0,cnt_sum=0;
while(true){
if(sum_a==sum_b){
sum_a+=a[cnt_a++];
sum_b+=b[cnt_b++];
}else if(sum_a>p[i].y;
vector vec(n); // 存
// 预处理,只需要耗时O(n^2),即可分堆,避免3层暴力的大量重复计算
for(int i=0; i{0,1},{1,0},{0,-1},{-1,0}};
boolean[][][] visited = new boolean[n][m][2 * k];
for (int step = 0; !qu.isEmpty(); step++) {
int num = qu.size();
for (int i = 0; i l>>r,res[r+l]++;
for(int i=1; iL>>R;
L*=2,R*=2;
if(L==0) cout
