写在开头
题主今年大三,可能是最后一次参加蓝桥杯,因此在这里发文纪念并附上部分解题记录。
赛前准备
我主要的刷题平台是 leetcode,按照大神给的题单刷了不少题,对于基本的算法与数据结构较为了解(如滑动窗口、并查集等),赛前倒是自信满满,赛后却是担惊受怕了一个月(还是因为太菜+心态不稳),好在最后擦线上了省一,否则我就要开启 Plan B 了(笑)。
1.【移动距离】
2.【客流量上限】
3.【可分解的正整数】
题目链接
https://www.luogu.com.cn/problem/P12134
解题思路
这是一道脑筋急转弯,很明显除了 1 之外的其他正整数都可以被构造出来,如 2 = -1 + 0 + 1 + 2,即可以通过负数将目标数 target 之前的所有正整数都给抵消掉。
最终代码如下:
#include <bits/stdc++.h>
// #pragma GCC optimize(2)
// #define int long long
using namespace std;
const int N = 100000 + 10;
void init(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
}
void solve(){
int n = 0, val = 0;
long long cnt = 0;
cin >> n;
while (n --){
cin >> val;
if (val > 1){
++ cnt;
}
}
cout << cnt << endl;
}
signed main() {
init();
solve();
// system("pause");
return 0;
}
考场实况
正解这是我在后面检查的时候发现的,一开始的思路是使用前缀和 + 二分。题目要求检查 target 是否可以由连续的正整数求和生成,等价于求是否存在一个区间 [l, r],使得 sum[l, r] = target(sum[l, r] 为 l~r 的和)。因此我们可以预处理出 1 ~ N 的和,然后通过二分查找检查是否存在。但是实际上 N 需要取到 1e9 才保险,这显然会超时。(所以预留半个小时回顾代码还是十分重要的)
4.【产值调整】
题目链接
https://www.luogu.com.cn/problem/P12133
解题思路
这又是一道脑筋急转弯,我们可以简单枚举一下A、B、C 迭代两轮的值,发现如下规律:A、B、C 的值会越来越趋近于混合平均,即若迭代次数 k 足够大,那么最终 A、B、C 的值会相等。而当三者相等时,继续迭代结果也不会改变。
最终代码如下:
#include <bits/stdc++.h>
// #pragma GCC optimize(2)
// #define int long long
using namespace std;
const int N = 100000 + 10;
void init(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
}
void solve(){
int t = 0;
int a, b, c, k;
int tmpa, tmpb, tmpc;
cin >> t;
while (t --){
cin >> a >> b >> c >> k;
while (k --){
if (a == b && b == c){
break;
}
tmpa = (b + c) / 2;
tmpb = (a + c) / 2;
tmpc = (a + b) / 2;
a = tmpa;
b = tmpb;
c = tmpc;
}
cout << a << " " << b << " " << c << endl;
}
}
signed main() {
init();
solve();
// system("pause");
return 0;
}
考场实况
完美错过正解,考试时想得太复杂了,一度打表找规律(企图使用公式一行搞定),但是这是第二题啊,怎么可能这么 ex ,最终红温并且推导失败,交了一发暴力(上述代码没有判断 a = b = c 情况的版本),最终 gg。
5.【画展布置】
题目链接
https://www.luogu.com.cn/problem/P12134
解题思路
这又是一道贪心 + 滑动窗口。显然我们需要对原序列进行排序,因为我们不可能放着价值接近的画不选转而选价值相差大的。而考试时真正令我困惑的是选的序列是否必须是连续的,比如xxx。这有点像贪心中的轮换论证。
最终代码如下:
#include <bits/stdc++.h>
// #pragma GCC optimize(2)
// #define int long long
using namespace std;
const int N = 100000 + 10;
void init(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
}
void solve(){
int n = 0, m = 0;
cin >> n >> m;
vector<int> paints(n, 0);
for (int i = 0; i < n; ++ i){
cin >> paints[i];
}
sort(paints.begin(), paints.end());
vector<long long> diff(n - 1, 0);
for (int i = 1; i < n; ++ i){
diff[i - 1] = 1ll * paints[i] * paints[i] - 1ll * paints[i - 1] * paints[i - 1];
}
// 滑动窗口,选 m - 1 个差值
-- m;
long long res = LLONG_MAX, cur = 0;
for (int l = 0, r = 0; r < n - 1; ++ r){
cur += diff[r];
if (r - l + 1 == m){
res = min(res, cur);
cur -= diff[l ++];
}
}
cout << res << endl;
}
signed main() {
init();
solve();
// system("pause");
return 0;
}
考场实况
排完序后被选择能否连续困扰许久(妈的真是弱智 ),最后选择摆烂,写了一个自以为不错的 dp(就是 dp 选与不选的思想),过了样例,但肯定超时。
6.【水质检测】
题目链接
https://www.luogu.com.cn/problem/P12135
解题思路
这是一道贪心 + 双指针。显然,我们从左边开始枚举,保证左侧区域是联通的,并记录上下河床最靠右的检测器的位置。其中的贪心思想体现在如何更新上下河床最靠右的检测器。
最终代码如下:
#include <bits/stdc++.h>
// #pragma GCC optimize(2)
// #define int long long
using namespace std;
const int N = 100000 + 10;
void init(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
}
void solve(){
// 双指针
string s[2];
cin >> s[0];
cin >> s[1];
int n = s[0].size();
long long res1 = 0;
int up_left = -1, down_left = -1;
for (int i = 0; i < n; ++ i){
if (s[0][i] == '#' && s[1][i] == '#'){
if (up_left != -1 && down_left != -1){
res1 += min(i - up_left - 1, i - down_left - 1);
} else if (up_left != -1){
res1 += i - up_left - 1;
} else if (down_left != -1){
res1 += i - down_left - 1;
}
up_left = down_left = i;
} else if (s[0][i] == '#'){
if (up_left != -1 && down_left != -1){
res1 += min(i - up_left - 1, i - down_left);
if (i - up_left - 1 >= i - down_left){
down_left = i;
}
} else if (up_left != -1){
res1 += i - up_left - 1;
} else if (down_left != -1){
res1 += i - down_left;
down_left = i;
}
up_left = i;
} else if (s[1][i] == '#'){
if (up_left != -1 && down_left != -1){
res1 += min(i - up_left, i - down_left - 1);
if (i - up_left <= i - down_left - 1){
up_left = i;
}
} else if (up_left != -1){
res1 += i - up_left;
up_left = i;
} else if (down_left != -1){
res1 += i - down_left - 1;
}
down_left = i;
}
}
cout << res1 << endl;
}
signed main() {
init();
solve();
// system("pause");
return 0;
}
(代码实在是过于丑陋了,感觉都像是模拟了)
考场实况
基本思路正确,但是忘记了贪心时及时更新最右检测器的位置,痛失满分(大雾)。
7.【生产车间】
题目链接
https://www.luogu.com.cn/problem/P12136
解题思路
看到题解需要使用树状数组,nnd 没学过,不会。
考场实况
瞅了五分钟,没什么思路,感觉像是图的题,过于麻烦 + 时间不够,最后输出样例打卡。
8.【装修报价】
题目链接
https://www.luogu.com.cn/problem/P12137
解题思路
后续更新~
考场实况
我是检查完前面的题才写的最后一题,大概 20 min,暴力栈模拟,过了样例,骗分成功。
总结
本年度蓝桥杯省赛打的真是依托,实际分数大概 30 ~ 40,位于省一倒数第三页,太他妈的丑陋了 ,当然也是狗运好,混了一个省一。国赛时要保持心态,发挥出应有的水平,加油💪💪💪