有无友友对下答案,希望拿个国二
感谢蓝桥杯小程序友友的分享:第十六届蓝桥杯大赛软件赛决赛_JB.pdf 链接: https://pan.baidu.com/s/15UYJ9fHLcO9tVYJr-qsXmQ?pwd=6666 提取码: 6666
JAVA B组复盘
主要就是考场上写的代码
这份卷子难度不大,进四五年来最简单的卷子
感觉主要C和D比后面难,做了快2个小时,以为又要寄了;好在后面看起来都不难
都是考基础算法,最难的算法就到树状数组
但是思维难度还是有的,一堆找规律和分类讨论的题
很遗憾的是分类讨论刚好就是我的弱项,一般都要做很久,还不一定能对
后续分类讨论的题要多画图
这里需要很注意爆int,绝大部分题基本都会爆
1A 组合数 :
C n 2 ∗ C n 2 , n = 2026 C_n^2*C_n^2,n=2026 Cn2∗Cn2,n=2026
4207934255625
2B 线性dp
放弃,估计要半个小时,剩20分钟的时候开了一半不想开了,去记答案了
3C 分类讨论 +贪心
当时应该画图的,可惜了
估计只能拿一半
k<m的情况基本都错了,后续做题例子不要是那种对称的,服啦
我的弱项,做了快半个小时。还是漏情况
k表示有多少个字符相同,只看这个就行,顺序不重要
这时候就要讨论k有多少个正确答案
各种情况
5 0–5
11111
00000
k=0
0 5
1 4
2 3
3 2
4 1
5 0
5 0-5
11111
11100
k=3
0 2
1 3
2 4
3 5
4 4
5 3
5 0-5
11111
10000
k=1
0 4
1 5
2 4
3 3
4 2
5 1
4D 破环成链+分类讨论
弱项,耗时一个小时
先用破环成链找规律(从0开始简单),可以发现操作都是对称的,当n为奇数,只能到奇数或者偶数;当n为偶数,能到奇数和偶数;然后再分类k
5E 前缀和+优先队列
找出最大的区间和就行,用前缀和转为找点操作
找区间最大和:
sum[l,r]=sum[r]-sum[l-1],找sum[l-1]最小的就行,这里直接用优先队列了,其实用min应该也没事
优先队列找其中最小的,初始有个0
区间最大和=max(区间最大和,当前sum-当前堆顶)
res=sum+区间最大和*(k-1)
6F 求逆序对+找规律
这里逆着想简单,把当前数组变得有序,不就是个冒泡排序吗?
对称操作,步数应该是一样的
然后看交换两次等于没交换,其实同奇偶就行
求逆序对的方法很多,这里我数据范围少,直接用树状数组暴力求了
逆序对个数为cnt
-
如果cnt=0:0
不用操作,本来就一致 -
如果和M同奇偶:
cnt+M能被2整除
这里好像没必要分了,但是考试来不及细想
cnt<=m
:m
cnt>m
:((m-1)/cnt+1)*m
-
不同奇偶:-1
7G 状压dp
状压dp,但是不是二进制表示,{1,5,6}
这需要特别注意1,1和所有互质,需要很小心,很容易错
各种相邻的情况:
状态下标 上 下
0 1 1
1 1 5
2 1 6
3 5 1
4 5 6
5 6 1
6 6 5
相邻的情况就是这些
这里我的f[i][j]
表示为放好第i行(从1开始)状态为j的集合
初始化为:f[0][i]
都为1
状态计算:从i=2
开始
考试的时候是这么想的,但是不知道会不会抄错,唉,只测了1和2不确定是否有问题
状态 第i行:可由哪些转移过来,相加
11 0:0 1 2 3 4 5 6
15 1:0 2 3 4 5//i-1把下面为5的都去掉,1不用管,去1 6
16 2:0 1 3 5 6//去下6,去2 4
//坏了,这里可能抄错了,考试的时候写得是0 1 3 4 5//靠,后续写个程序验算下,n=2会不会有问题
//还好测试出来,好像能对,这个好像是对称的,有点慌
51 3:0 1 2 5 6//去上5,去3 4
56 4:0 1 5 6//去上5和下6,去3 4 2
61 5:0 1 2 3 4//去上6,去5 6
65 6:0 2 3 4//去上6和下5,去5 6 1
8H 找规律
不确定对不对,有点简单了
题目有点忘了
首先对于n,他的集合为{1,2,3,...,n-1,n}
,这里我能任意选择加减
这里我们用逆向思维,先求和然后在减去哪些想减的
最右能够达到sum=n*(n+1)/2
这里我们发现这个集合能够组成的数为1-sum
任意数
也就是说我们能减的数为:{2*k|1<=k<=sum}
所以我们能得到的数:sum-2*k
这里发现必然是同sum
同奇偶的
对于sum
而言n或者n+1
必须要为2^a(a>1)
质因子才能为偶数
但是这种做法显然太难了,没有那么多时间了
直接暴力吧,感觉应该能够拿挺多分的
//小小优化
n=sqrt(L*2)-1;//自己模拟了下,应该没问题,只要保证sum稍微比n小点就没事
暴力找n,找符合的第一个数
L<=sum&&(sum+L)%2==0
//如果结论没错,最多在4-10次肯定能找到答案,复杂度很低
9I 并查集
这个我也感觉我的做法太简单了,不确定对不对
跟算连通块个数差不多
int d[];//但是当前连通块中有多少条边
add(x,y){
int rx=find(x),ry=find(y);
if(rx==ry){
++d[rx];
}else{
p[rx]=ry;//ry成为新的祖宗
d[ry]+=d[rx]+1;//这个希望我考试的时候是写成+=,呜呜,有点忘了
}
}
res=max{连通块中最大的d[r]}
哎呀呀,这题其实气死我了,最后几题感觉太简单的一般都是自己出了问题,这时候一定回去看题和多造一点一般样例模拟,不要只模拟题目给的小样例
我这种做法,如果连通块(这里说的连通块都是大于两个点的)删边后变成了两个连通块,那么这时下轮删的时候是两个一起删,所以上面解法是错的。估计一分不得
这里想了一种做法,也是并查集,不确定是否正确:
我们可以观察到:
- 是从前往后删边,删第
i
条时,后面的i-1
都是在的。这里就有种感觉能否从后往前操作- 各个连通块之间其实是独立的,根据题目的意思,我们只看其中最大操作的一个连通块就行了
我们接着观察下操作:
- 要么就是连通了两块不连通的:
rx!=ry
这时候我们重点只需要看其中操作数最大的一块:d[ry]=max(d[rx],d[ry])+1
- 要么就是在连通块上加一条边:
rx==ry
这个不会改变连通性,只需要将权+1即可:d[ry]+=1
10J 树状数组+分类讨论
感觉也不难,可能有问题
由于只有两个数,情况特别少,分类讨论就完事了
- 含1的情况
mex(1,1)=2
mex(1,2)=3
mex(1,>=3)=2
mex(1,1)=2
- 不含1
mex(>=2,>=2)=1
直接算每种情况的贡献就行
这里我们[l,r]
需要的数据为:
cnt1
:区间中1的个数cnt2
:区间中2的个数cnt3
:区间中大于等于3的个数
这里涉及到修改,这里我们可以用类似求逆序对的方法,用树状数组修改以及求区间中某个数的个数,数据范围不大,不用离散化
tr1,tr2,tr3
:分别对应求上面三个值
答案的情况:
- 含1:
- 2 ∗ C c n t 1 2 2*C^2_{cnt1} 2∗Ccnt12
- 3 ∗ c n t 1 ∗ c n t 2 3*cnt1*cnt2 3∗cnt1∗cnt2
- 2 ∗ c n t 1 ∗ c n t 3 2*cnt1*cnt3 2∗cnt1∗cnt3
- 不含1: C c n t 2 + c n t 3 2 C_{cnt2+cnt3}^2 Ccnt2+cnt32
洛谷估分:95-115
update:国一