第十六届蓝桥杯C/C++B组省赛个人代码

A. 移动距离


  • 最后做的填空,凭感觉猜的。
  • 先往右走欧几里得距离,再往上转到目标点。
  • 证明需要画图,这里就不写了。
  • 不知道有反三角函数,求弧长用的实数域二分答案求角度占比。

B. 客流量上限


不会,第二个填空从来没做出来过。

C. 可分解的正整数


赛时看一眼填空不太好做,直奔C题。

没认真看题思考,只取了3的倍数(序列长度是3的),毫无疑问WA了

解题思路

  • 对于一个正整数\(n\),可以写成\(\sum_{i=-n+1}^{n}i\)。
  • \(n=1\)时,序列长度只为2。
  • 所以除了\(1\)都可以。

D. 产值调整


赛时直接猜,当操作次数非常多的时候,三个数会趋向于相等。

最大操作次数是\(log\)级别的,实在不会就打表,最多几十次就会相等。

AC代码

#include<bits/stdc++.h>

void Main() {
int a, b, c, k;
std::cin >> a >> b >> c >> k;
while (k--) {
int x = b + c >> 1;
int y = a + c >> 1;
int z = a + b >> 1;
a = x, b = y, c = z;
if (a == b && a == c) {
break;
}
}
std::cout << a << " " << b << " " << c << "\n";
} int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0), std::cout.tie(0);
int T = 1;
std::cin >> T;
while (T--) {
Main();
}
return 0;
}

E. 画展布置


解题思路

因为可以随便取\(m\)个,并打乱顺序,所以尽量取数值上较为集中的\(m\)个数。

先排个序,维护个前缀和,然后长度\(m\)的滑动窗口,取连续的\(m\)个即可。

  • 时间复杂度\(O(nlogn)\)。

AC代码

#include<bits/stdc++.h>

using i64 = long long;

void Main() {
int n, m;
std::cin >> n >> m;
std::vector<i64> a(n + 1);
for (int i = 1; i <= n; i++) {
std::cin >> a[i];
a[i] *= a[i];
}
sort(a.begin() + 1, a.end());
std::vector<i64> pre(n + 1);
for (int i = 1; i <= n; i++) {
pre[i] = pre[i - 1] + a[i] - a[i - 1];
}
i64 ans = 1e18;
for (int i = m; i <= n; i++) {
ans = std::min(ans, pre[i] - pre[i - m + 1]);
}
std::cout << ans << "\n";
} int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0), std::cout.tie(0);
int T = 1;
// std::cin >> T;
while (T--) {
Main();
}
return 0;
}

F. 水质检测


赛时贪心漏情况了,没考虑全面,WA一半。

解题思路

  • 最初思路肯定是把所有联通块挑出来,相邻的联通块连接。
  • 为了方便,把竖着两个字符变成了二进制数。'#'表示\(1\),'.'表示\(0\)。
  • 时间复杂度\(O(n)\)。

赛时错误代码

#include<bits/stdc++.h>

void Main() {
std::string s[2];
std::cin >> s[0] >> s[1];
std::vector<std::pair<int, int>> piece;
for (int i = 0; i < s[0].size(); i++) {
int t = 0;
for (int j = 0; j < 2; j++) {
if (s[j][i] == '#') {
t += 1 << (1 - j);
}
}
if (t) {
piece.push_back({i, t});
}
}
int ans = 0;
for (int i = 1; i < piece.size(); i++) {
auto &[l, v1] = piece[i - 1];
auto &[r, v2] = piece[i];
if (r - l == 1 && v1 & v2) {
continue;
}
if (v1 == 3 || v2 == 3 || v1 == v2) {
ans += r - l - 1;
} else {
ans += r - l;
// v2 = 3;
}
}
std::cout << ans << "\n";
} int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0), std::cout.tie(0);
int T = 1;
// std::cin >> T;
while (T--) {
Main();
}
return 0;
}

AC代码

#include<bits/stdc++.h>

void Main() {
std::string s[2];
std::cin >> s[0] >> s[1];
std::vector<std::pair<int, int>> piece;
for (int i = 0; i < s[0].size(); i++) {
int t = 0;
for (int j = 0; j < 2; j++) {
if (s[j][i] == '#') {
t += 1 << (1 - j);
}
}
if (t) {
piece.push_back({i, t});
}
}
int ans = 0;
for (int i = 1; i < piece.size(); i++) {
auto &[l, v1] = piece[i - 1];
auto &[r, v2] = piece[i];
if (r - l == 1 && v1 & v2) {
continue;
}
if (v1 == 3 || v2 == 3 || v1 == v2) {
ans += r - l - 1;
} else {
ans += r - l;
v2 = 3;
}
}
std::cout << ans << "\n";
} int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0), std::cout.tie(0);
int T = 1;
// std::cin >> T;
while (T--) {
Main();
}
return 0;
}

区别就是else里是否对\(v2\)进行赋值\(3\)。

对于两个联通块连接处一上一下(一个\(1\),一个\(2\))的情况,比如\(21\),可以变成\(23\)或者\(31\)。

但是对于连着三个连通块上下上或者下上下的情况,比如\(212\),变成\(232\)是最优的,而变成\(312\),则再需要一个变成\(332\)才能联通三个。

所以当上述所述情况时,尽量选择让后者变成\(3\)(两个'#'),这样就有可能在联通第三个联通块时少用一个。

G. 生产车间


赛时没做数据,过样例直接交了,估计WA一半。

解题思路

  • 树上背包
  • 从最底层往上,用\(u\)节点的子节点对\(u\)进行背包。
  • dp[i][j]表示节点\(i\)能否获得\(j\)的价值。
  • 为什么要从下往上,因为要使用子节点对父节点更新信息时,你要保证子节点的信息已经全部更新完了。
  • 整体过程直接DFS,回溯后就可以保证已经访问并更新了所有子节点,再对当前节点dp。我赛时还记录了深度,按层来,完全按照由下到上,有点蠢了。
  • 时间复杂度感觉是\(O(n^3)\),不知道为啥能跑这么快。
  • 好像可以\(bitset\)优化,也有人用FFT。(暂时不会)

赛时错误代码+错误指出(就差一点,没考虑到根节点也有可能度是1,被迫当成叶子了)

#include<bits/stdc++.h>
using namespace std; #define int long long using i64 = long long;
using i128 = __int128;
using u64 = unsigned long long; int n;
const int N = 1e3 + 2;
int d[N], fa[N], dp[N][N], a[N];
vector<vector<int>> e(N), D(N); void dfs(int x, int f) {
fa[x] = f;
d[x] = d[f] + 1;
for (auto u : e[x]) {
if (u != f) {
dfs(u, x);
}
}
} void Main() {
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
for (int i = 1; i < n; i++) {
int u, v;
cin >> u >> v;
e[u].push_back(v);
e[v].push_back(u);
}
dfs(1, 0);
for (int i = 1; i <= n; i++) { // 这里不该有1,从2开始,单独D[1].push_back(1)就AC了,哭死
if (e[i].size() == 1) {
dp[i][a[i]] = a[i];
}
D[d[i]].push_back(i);
}
int len = n;
while (1) {
set<int> st;
while (len > 0 && !D[len].size()) {
len--;
}
if (len == 0) {
break;
}
for (auto i : D[len]) {
st.insert(fa[i]);
}
for (auto i : st) {
for (auto j : e[i]) {
if (j != fa[i]) {
for (int k = a[i]; k >= 0; k--) {
for (int kk = a[j]; kk >= 0; kk--) {
if (k >= kk) {
dp[i][k] = max(dp[i][k], dp[i][k - kk] + dp[j][kk]);
}
}
}
}
}
}
len--;
}
int ans = 0;
for (int i = 0; i <= a[1]; i++) {
ans = max(ans, dp[1][i]);
}
cout << ans << "\n";
} signed main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0), std::cout.tie(0);
int T = 1;
// std::cin >> T;
while (T--) {
Main();
}
return 0;
}

AC代码

#include<bits/stdc++.h>

const int N = 1e3 + 5;

int n;
int dp[N][N], a[N];
std::vector<int> e[N]; void dfs(int x, int fa) {
if (e[x].size() == 1 && x != 1) {
dp[x][0] = 1;
dp[x][a[x]] = 1;
return;
}
for (auto u : e[x]) {
if (u != fa) {
dfs(u, x);
}
}
dp[x][0] = 1;
for (auto i : e[x]) {
if (i != fa) {
for (int j = a[x]; j >= 0; j--) {
for (int k = 0; k <= a[i] && j + k <= a[x]; k++) {
dp[x][j + k] |= dp[x][j] & dp[i][k];
}
}
}
}
} void Main() {
std::cin >> n;
for (int i = 1; i <= n; i++) {
std::cin >> a[i];
}
for (int i = 1; i < n; i++) {
int u, v;
std::cin >> u >> v;
e[u].push_back(v);
e[v].push_back(u);
}
dfs(1, 0);
for (int i = a[1]; i >= 0; i--) {
if (dp[1][i]) {
std::cout << i << "\n";
return;
}
}
} int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0), std::cout.tie(0);
int T = 1;
// std::cin >> T;
while (T--) {
Main();
}
return 0;
}

H. 装修报价


第一眼感觉不太好做,赛时还搓了半天组合数板子,发现没啥用。

试了好几种思路,写了个暴力DFS当对拍,来验证想法对不对,试出来了。

解题思路

  • 一道不算太难的小规律题。
  • \(a_i\)能否对答案产生贡献,取决于它前面的符号。
  • 当\(a_i\)前面的符号是\(+\)时,可以将它变成\(-\),这样这两种方案的结果相加,就把这个数字给抵消了。
  • 一个特殊的点,\(a_1\)前面的符号只能是\(+\),所以\(a_1\)(包括和它相异或的异或值)一定会产生\(a_1 \times方案数\)的贡献。
  • 答案就是前\(i\)个数异或前缀和来产生贡献,下一个符号一定不是异或,后面的符号可以随便,三种其中一个,方案数\(2 \times3^k\)。
  • 然后漏了一种,所有数异或在一块,额外加上就行。就是因为这个,调了半天。
  • 时间复杂度\(O(nlogn)\)。

AC代码

#include<bits/stdc++.h>

using i64 = long long;

constexpr int mod = 1e9 + 7;

i64 power(i64 a, int b) {
if (b < 0) {
return 0;
}
i64 res = 1;
for (; b; a = a * a % mod, b >>= 1) {
if (b & 1) {
res = res * a % mod;
}
}
return res;
} void Main() {
int n;
std::cin >> n;
std::vector<int> a(n);
for (int i = 0; i < n; i++) {
std::cin >> a[i];
}
int pre = a[0];
int ans = 0;
for (int i = 0; i < n - 1; i++) {
ans = (ans + pre * 2 % mod * power(3, n - i - 2) % mod) % mod;
pre ^= a[i + 1];
}
ans = (ans + pre) % mod;
std::cout << ans << "\n";
} int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0), std::cout.tie(0);
int T = 1;
// std::cin >> T;
while (T--) {
Main();
}
return 0;
}

总结


总的来说,唐完了,远不如去年稳。

半小时写CDEF,四个题错两个,快速把简单题做错,然后去做麻烦的题,幸好最后一个AC了。

有的细节地方没处理好,树上背包差点AC,oi赛制自己造小数据测不出来,一判就WA。

2025年 蓝桥杯C/C++B组省赛 个人代码的更多相关文章

  1. 2016 第七届蓝桥杯 c/c++ B组省赛真题及解题报告

    2016 第七届蓝桥杯 c/c++ B组省赛真题及解题报告 勘误1:第6题第4个 if最后一个条件粗心写错了,答案应为1580. 条件应为abs(a[3]-a[7])!=1,宝宝心理苦啊.!感谢zzh ...

  2. 2015年第六届蓝桥杯C/C++B组省赛题目解析

    一.奖券数目 有些人很迷信数字,比如带“4”的数字,认为和“死”谐音,就觉得不吉利.虽然这些说法纯属无稽之谈,但有时还要迎合大众的需求.某抽奖活动的奖券号码是5位数(10000-99999),要求其中 ...

  3. 2013年第四届蓝桥杯C/C++B组省赛题目解析

    一. 高斯日记 大数学家高斯有个好习惯:无论如何都要记日记. 他的日记有个与众不同的地方,他从不注明年月日,而是用一个整数代替,比如:4210 后来人们知道,那个整数就是日期,它表示那一天是高斯出生后 ...

  4. 第九届蓝桥杯C/C++B组省赛感想

    因为做了近三年的初赛题,都对了5题+,所以这次比赛前信心满满,心里想最少水个省二没问题.可我怎么知道今年的套路居然和以前不一样了!一题深搜都没有,想想一周前做的第七届初赛题,10题有3.4题深搜题. ...

  5. 2017第八届蓝桥杯C/C++ B组省赛-日期问题

    标题:日期问题 小明正在整理一批历史文献.这些历史文献中出现了很多日期.小明知道这些日期都在1960年1月1日至2059年12月31日.令小明头疼的是,这些日期采用的格式非常不统一,有采用年/月/日的 ...

  6. 2017第八届蓝桥杯C/C++ B组省赛-购物单

    标题: 购物单 小明刚刚找到工作,老板人很好,只是老板夫人很爱购物.老板忙的时候经常让小明帮忙到商场代为购物.小明很厌烦,但又不好推辞. 这不,XX大促销又来了!老板夫人开出了长长的购物单,都是有打折 ...

  7. 2017第八届蓝桥杯C/C++ B组省赛-等差素数列

    标题:等差素数列 2,3,5,7,11,13,....是素数序列. 类似:7,37,67,97,127,157 这样完全由素数组成的等差数列,叫等差素数数列. 上边的数列公差为30,长度为6. 200 ...

  8. 2014年第五届蓝桥杯C/C++B组省赛题目解析

    一.啤酒和饮料 啤酒每罐2.3元,饮料每罐1.9元.小明买了若干啤酒和饮料,一共花了82.3元. 我们还知道他买的啤酒比饮料的数量少,请你计算他买了几罐啤酒. 注意:答案是一个整数.请通过浏览器提交答 ...

  9. 2017年第八届蓝桥杯C/C++B组省赛题目解析

    一. 购物单 小明刚刚找到工作,老板人很好,只是老板夫人很爱购物.老板忙的时候经常让小明帮忙到商场代为购物.小明很厌烦,但又不好推辞. 这不,XX大促销又来了!老板夫人开出了长长的购物单,都是有打折优 ...

  10. 2016年第七届蓝桥杯C/C++B组省赛题目解析

    题目1:煤球数目 有一堆煤球,堆成三角棱锥形.具体:第一层放1个,第二层3个(排列成三角形),第三层6个(排列成三角形),第四层10个(排列成三角形),....如果一共有100层,共有多少个煤球?请填 ...

随机推荐

  1. Burp Suite 企业级深度实战教程

    第一部分:环境搭建与高级配置 1.1 专业版激活与插件生态 # 专业版激活(Linux) java -jar -Xmx2048m burpsuite_pro.jar --activate --acti ...

  2. Java源码分析系列笔记-3.volatile

    目录 1. 是什么 2. 什么情况 volatile 比 synchronized 更合适 2.1. 例子 2.2. 无法停止的原因分析 2.3. 解决方法 2.4. volatile vs sync ...

  3. Linux开放防火墙指定端口

    方法一 开启8011端口 /sbin/iptables -I INPUT -p tcp --dport 8011 -j ACCEPT 保存配置 /etc/rc.d/init.d/iptables sa ...

  4. Kong入门学习实践(8)流量控制插件

    Kong的一大特色就在于强大的可扩展性,具体实现方式就是插件.一来Kong已经提供了很多内置的插件,二来我们也可以使用Lua语言自定义开发插件.今天,我们就来了解一些常用的流量控制插件. 关于流量控制 ...

  5. C# WInFomr 窗体圆角

    #region 设置窗体圆角 /// <summary> /// 设置窗体圆角 /// </summary> /// <param name="f"& ...

  6. 如何在非vue组件中使用vuex

    简介 RT,有的时候想使用保存在vuex里面的东西 link https://laracasts.com/discuss/channels/vue/vuex-accessing-vuex-outsid ...

  7. sublime text 常见问题及解决

    Error Loading Error loading colour scheme Packages/ThemeDefault/Widgets.stTheme: Unable to open Pack ...

  8. 使用rclone将linux服务器上的文件夹同步到nextcloud

    最近公司在用nextcloud管理文件,我写了一个python脚本,领导想看中间生成的图片,让我把图片同步到nextcloud上.上网搜了一些方法,最终用rclone实现,以下是实现过程. 服务器版本 ...

  9. SciTech-Mathmatics-Probability+Statistics-Population Vs. Sampling: Representative Samples + How to obtain Samples

    Difference: Population vs. Sample BY ZACH BOBBITTPOSTED ON NOVEMBER 27, 2020 Often in statistics we' ...

  10. 官方文档没告诉你的:通过抓包,深入揭秘MCP协议底层通信

    大家好,今天我们来深入探讨一个很有意思的话题--MCP(Model Context Protocol). MCP 是Anthropic发起的一种开放协议,旨在标准化应用程序向大型语言模型(LLM)提供 ...