第十四届蓝桥杯大赛软件赛省赛 C/C++ 大学 B 组
试题 A: 日期统计(dfs+剪枝/暴力枚举)
本题总分:
【问题描述】
小蓝现在有一个长度为
5 6 8 6 9 1 6 1 2 4 9 1 9 8 2 3 6 4 7 7 5 9 5 0 3 8 7 5 8 1 5 8 6 1 8 3 0 3 7 9 2 7 0 5 8 8 5 7 0 9 9 1 9 4 4 6 8 6 3 3 8 5 1 6 3 4 6 7 0 7 8 2 7 6 8 9 5 6 5 6 1 4 0 1 0 0 9 4 8 0 9 1 2 8 5 0 2 5 3 3
现在他想要从这个数组中寻找一些满足以下条件的子序列:
1. 子序列的长度为
2. 这个子序列可以按照下标顺序组成一个
请你帮小蓝计算下按上述条件一共能找到多少个不同 的
对于相同的日期你只需要统计一次即可。
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
点击查看代码
#include <bits/stdc++.h> #define int long long #define IOS ios::sync_with_stdio(false) #define int long long using namespace std; const int N = 110; int a[N], ans; bool st[20240000]; bool vis[20240000]; bool check(int date) { if(st[date]) return false; st[date] = true; int m = date / 100 % 100; int d = date % 100; if(m < 1||m > 12) return false; if(m == 1||m == 3||m == 5||m == 7||m == 8||m == 10||m == 12) { if(d >= 1&&d <= 31) return true; } else if(m == 2) { if(d >= 1&&d <= 28) return true; } else if(d >= 1&&d <= 30) return true; return false; } void dfs(int x, int pos, int date) { if(x == 100) return ; if(pos == 8) { if(check(date)) ans ++; return ; } if((pos == 0&&a[x] == 2)|| (pos == 1&&a[x] == 0)|| (pos == 2&&a[x] == 2)|| (pos == 3&&a[x] == 3)|| (pos == 4&&a[x] >= 0&&a[x] <= 1)|| (pos == 5&&a[x] >= 0&&a[x] <= 9)|| (pos == 6&&a[x] >= 0&&a[x] <= 3)|| (pos == 7&&a[x] >= 0&&a[x] <= 9)) (dfs(x + 1, pos + 1, date * 10 + a[x])); dfs(x + 1, pos, date); } void solve() { for(int i = 0; i < 100; i ++) cin >> a[i]; dfs(0, 0, 0); cout << ans << '\n'; } signed main() { IOS; int _ = 1; // cin >> _; while(_ --) solve(); return _ ^ _; } /* 5 6 8 6 9 1 6 1 2 4 9 1 9 8 2 3 6 4 7 7 5 9 5 0 3 8 7 5 8 1 5 8 6 1 8 3 0 3 7 9 2 7 0 5 8 8 5 7 0 9 9 1 9 4 4 6 8 6 3 3 8 5 1 6 3 4 6 7 0 7 8 2 7 6 8 9 5 6 5 6 1 4 0 1 0 0 9 4 8 0 9 1 2 8 5 0 2 5 3 3 */
试题 B: 01 串的熵(循环枚举)
本题总分:
【问题描述】
对于一个长度为
比如,对于
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
点击查看代码
#include <bits/stdc++.h> #define ld long double using namespace std; const int N = 23333333; const ld eps = 1e-4, P = 11625907.5798; int main() { int n = N / 2 + 1; cout << fixed << setprecision(10); for(int i = 1; i < n; i ++) { int j = N - i; ld t = -1.0 * i * i / N * log2(1.0 * i / N); ld s = -1.0 * j * j / N * log2(1.0 * j / N); if(fabs(t + s - P) < eps) { cout << i << '\n'; return 0; } } return 0; } //11027421
试题 C: 冶炼金属(二分/模拟)
时间限制:
【问题描述】
小蓝有一个神奇的炉子用于将普通金属
现在给出了
投入了
根据这
多少,题目保证评测数据不存在无解的情况。
【输入格式】
第一行一个整数
接下来输入
【输出格式】
输出两个整数,分别表示
【样例输入】
3
75 3
53 2
59 2
【样例输出】
20 25
【样例说明】
当
当
记录。
且再也找不到比
【评测用例与约定】
对于
对于
对于
点击查看代码
#include <bits/stdc++.h> #define IOS ios::sync_with_stdio(false);cin.tie(nullptr),cout.tie(nullptr) #define int long long using namespace std; const int N = 1e4 + 10; int a[N], b[N]; int n, mx, mn; bool check(int x) { for(int i = 1; i <= n; i ++) if(a[i] / x > b[i]) return false; return true; } bool check2(int x) { for(int i = 1; i <= n; i ++) if(a[i] / x < b[i]) return false; return true; } signed main() { cin >> n; for(int i = 1; i <= n; i ++) cin >> a[i] >> b[i]; int l = 1, r = 1e10, m; while(l < r) { m = l + r >> 1; if(check(m)) r = m; else l = m + 1; } mn = l; l = 1, r = 1e10; while(l < r) { m = l + r + 1 >> 1; if(check2(m)) l = m; else r = m - 1; } mx = l; cout << mn << ' ' << mx << '\n'; return 0; }
试题 D: 飞机降落(DFS)
时间限制:
【问题描述】
一架飞机降落完毕时,另一架飞机可以立即在同一时刻开始降落,但是不能在前一架飞机完成降落前开始降落。
请你判断
【输入格式】
输入包含多组数据。
第一行包含一个整数
对于每组数据,第一行包含一个整数
以下
【输出格式】
对于每组数据,输出
【样例输入】
2
3
0 100 10
10 10 10
0 2 20
3
0 10 20
10 10 20
20 10 20
【样例输出】
YES
NO
【样例说明】
对于第一组数据,可以安排第
对于第二组数据,无论如何安排,都会有飞机不能及时降落。
【评测用例与约定】
对于
对于
点击查看代码
#include <bits/stdc++.h> #define IOS ios::sync_with_stdio(false);cin.tie(nullptr),cout.tie(nullptr) #define int long long using namespace std; const int N = 20; int n, t[N], d[N], l[N]; bool f, p[N]; void dfs(int x, int tim) { if(f) return ; if(x == n) { f = true; return ; } for(int i = 1; i <= n; i ++) if(!p[i]&&tim <= t[i] + d[i]) { p[i] = true; dfs(x + 1, max(t[i], tim) + l[i]); if(f) return ; p[i] = false; } } void solve() { cin >> n; for(int i = 1; i <= n; i ++) { cin >> t[i] >> d[i] >> l[i]; p[i] = false; } f = false; dfs(0, 0); if(f) cout << "YES\n"; else cout << "NO\n"; } signed main() { IOS; int _ = 1; cin >> _; while(_ --) solve(); return _ ^ _; }
试题 E: 接龙数列(线性dp,最长上升子序列)
时间限制:
【问题描述】
对于一个长度为
例如
的首位数字不等于
现在给定一个长度为
【输入格式】
第一行包含一个整数
第二行包含
【输出格式】
一个整数代表答案。
【样例输入】
5
11 121 22 12 2023
【样例输出】
1
【样例说明】
删除
【评测用例与约定】
对于
对于
对于
点击查看代码
#include <bits/stdc++.h> #define IOS ios::sync_with_stdio(false);cin.tie(nullptr),cout.tie(nullptr) #define int long long using namespace std; const int N = 20; string s; int f[N], n; void solve() { cin >> n; for(int i = 1; i <= n; i ++) { cin >> s; int a = s[0] - '0'; int b = s[s.size() - 1] - '0'; f[b] = max(f[b], f[a] + 1); // int x; // cin >> x; // vector<int> ve; // while(x) // ve.push_back(x % 10), x /= 10; // int a = *ve.begin(), b = ve.back(); // f[a] = max(f[a], f[b] + 1); } int ans = 0; for(int i = 0; i < 10; i ++) ans = max(ans, f[i]); cout << n - ans << '\n'; } signed main() { IOS; int _ = 1; // cin >> _; while(_ --) solve(); return _ ^ _; }
试题 F: 岛屿个数(DFS)
时间限制:
【问题描述】
小蓝得到了一副大小为
每个岛屿由在上/下/左/右四个方向上相邻的
在岛屿
他们的坐标能够组成一个这样的排列:
请问这个地图上共有多少个岛屿?在进行统计时不需要统计子岛屿的数目。
【输入格式】
第一行一个整数
接下来输入
【输出格式】
对于每组数据,输出一行,包含一个整数表示答案。
【样例输入】
2
5 5
01111
11001
10101
10001
11111
5 6
111111
100001
010101
100001
111111
【样例输出】
1
3
【样例说明】
对于第一组数据,包含两个岛屿,下面用不同的数字进行了区分:
01111
11001
10201
10001
11111
岛屿
对于第二组数据,包含三个岛屿,下面用不同的数字进行了区分:
111111
100001
020301
100001
111111
注意岛屿
“环”。
【评测用例与约定】
对于
对于
点击查看代码
#include <bits/stdc++.h> #define IOS ios::sync_with_stdio(false);cin.tie(nullptr),cout.tie(nullptr) // #define int long long using namespace std; const int N = 60; int n, m; string mp[N]; bool st[N][N], used[N][N]; int dx[] = {0, 0, 1, -1, 1, -1, 1, -1}; int dy[] = {1, -1, 0, 0, 1, 1, -1, -1}; void bfs_col(int x, int y) { queue<int> qx, qy; qx.push(x), qy.push(y), st[x][y] = 1; while(!qx.empty()) { x = qx.front(), qx.pop(); y = qy.front(), qy.pop(); for(int i = 0; i < 4; i ++) { int nx = x + dx[i]; int ny = y + dy[i]; if(nx < 0||nx >= n||ny < 0|ny >= m||st[nx][ny]||mp[nx][ny] == '0') continue; qx.push(nx), qy.push(ny), st[nx][ny] = 1; } } } bool bfs_out(int x, int y) { for(int i = 0; i < n; i ++) for(int j = 0; j < m; j ++) used[i][j] = 0; queue<int> qx, qy; qx.push(x), qy.push(y), used[x][y] = 1; while(!qx.empty()) { x = qx.front(), qx.pop(); y = qy.front(), qy.pop(); if(x == 0||x == n - 1||y == 0||y == m - 1) return true; for(int i = 0; i < 8; i ++) { int nx = x + dx[i]; int ny = y + dy[i]; if(nx < 0||nx >= n||ny < 0|ny >= m||used[nx][ny]||mp[nx][ny] == '1') continue; qx.push(nx), qy.push(ny), used[nx][ny] = 1; } } return false; } void solve() { cin >> n >> m; for(int i = 0; i < n; i ++) { cin >> mp[i]; for(int j = 0; j < m; j ++) st[i][j] = 0; } int ans = 0; for(int i = 0; i < n; i ++) for(int j = 0; j < m; j ++) if(!st[i][j]&&mp[i][j] == '1') { bfs_col(i, j); if(bfs_out(i, j)) ans ++; } cout << ans << '\n'; } signed main() { IOS; int _ = 1; cin >> _; while(_ --) solve(); return _ ^ _; } /* 2 5 5 01111 11001 10101 10001 11111 5 6 111111 100001 010101 100001 111111 */
试题 G: 子串简写(线性dp/模拟)
时间限制:
【问题描述】
程序猿圈子里正在流行一种很新的简写方法:对于一个字符串,只保留首尾字符,将首尾字符之间的所有字符用这部分的长度代替。例如
在本题中,我们规定长度大于等于
给定一个字符串
【输入格式】
第一行包含一个整数
第二行包含一个字符串
【输出格式】
第二行包含一个字符串 S 和两个字符 c1 和 c2。
【样例输入】
4
abababdb a b
【样例输出】
6
【样例说明】
符合条件的子串如下所示,中括号内是该子串:
【评测用例与约定】
对于
对于
是小写字母。
点击查看代码
#include <bits/stdc++.h> #define IOS ios::sync_with_stdio(false);cin.tie(nullptr),cout.tie(nullptr) #define int long long using namespace std; string s; char c1, c2; int n, ans, k, t; void solve() { cin >> k >> s >> c1 >> c2; n = s.size(); for(int i = k - 1, j = 0; i < n; i ++, j ++) { if(s[j] == c1) t ++; if(s[i] == c2) ans += t; } cout << ans << '\n'; } signed main() { IOS; int _ = 1; // cin >> _; while(_ --) solve(); return _ ^ _; }
试题 H: 整数删除(链表+优先队列)
时间限制:
【问题描述】
给定一个长度为
每次选择数列中最小的整数(如果最小值不止一个,选择最靠前的),将其删除。并把与它相邻的整数加上被删除的数值。
输出
【输入格式】
第一行包含两个整数
第二行包含
【输出格式】
输出
【样例输入】
5 3
1 4 2 8 7
【样例输出】
17 7
【样例说明】
数列变化如下,中括号里的数是当次操作中被选择的数:
【评测用例与约定】
对于
对于
点击查看代码
#include <bits/stdc++.h> #define IOS ios::sync_with_stdio(false);cin.tie(nullptr),cout.tie(nullptr) #define int long long #define fi first #define se second using namespace std; const int N = 5e5 + 10; typedef pair<int, int> pii; int n, k, pre[N], ne[N], a[N]; priority_queue<pii> q; void solve() { cin >> n >> k; for(int i = 1; i <= n; i ++) { cin >> a[i]; pre[i] = i - 1; ne[i] = i + 1; q.push({-a[i], -i}); } pre[1] = -1; ne[n] = -1; while(k --) { pii now; do { now = q.top(), q.pop(); now.fi = - now.fi, now.se = -now.se; }while(a[now.se] != now.fi); int PRE = pre[now.se]; int NE = ne[now.se]; if(PRE != -1) { a[PRE] += now.fi; q.push({-a[PRE], -PRE}); ne[PRE] = NE; } if(NE != -1) { a[NE] += now.fi; q.push({-a[NE], -NE}); pre[NE] = PRE; } a[now.se] = -1; } for(int i = 1; i <= n; i ++) if(a[i] != -1) cout << a[i] << ' '; } signed main() { IOS; int _ = 1; // cin >> _; while(_ --) solve(); return _ ^ _; }
试题 I: 景区导游(LCA)
时间限制:
【问题描述】
某景区一共有
小明是这个景区的资深导游,他每天都要按固定顺序带客人游览其中
请你对任意一个
【输入格式】
第一行包含
以下
最后一行包含
【输出格式】
输出
【样例输入】
6 4
1 2 1
1 3 1
3 4 2
3 5 2
4 6 3
2 6 5 1
【样例输出】
10 7 13 14
【样例说明】
原路线是
当跳过
当跳过
当跳过
当跳过 1 时,路线时
【评测用例与约定】
对于
对于
对于
点击查看代码
#include <bits/stdc++.h> #define IOS ios::sync_with_stdio(false);cin.tie(nullptr),cout.tie(nullptr) #define int long long #define fi first #define se second using namespace std; const int N = 1e5 + 10; vector<int> e[N], w[N]; int fa[N][21], dep[N], dis[N]; int a[N], b[N]; int n, k; void dfs(int u, int Fa) { dep[u] = dep[Fa] + 1; fa[u][0] = Fa; for(int i = 1; i <= 20; i ++) fa[u][i] = fa[fa[u][i - 1]][i - 1]; for(int i = 0; i < e[u].size(); i ++) { int v = e[u][i], ww = w[u][i]; if(v == Fa) continue; dis[v] = dis[u] + ww; dfs(v, u); } } int LCA(int u, int v) { if(dep[u] < dep[v]) swap(u, v); for(int i = 20; i >= 0; i --) if(dep[fa[u][i]] >= dep[v]) u = fa[u][i]; if(u == v) return u; for(int i = 20; i >= 0; i --) if(fa[u][i] != fa[v][i]) { u = fa[u][i]; v = fa[v][i]; } return fa[u][0]; } int path_dis(int u, int v) { if(!u||!v) return 0; return dis[u] + dis[v] - 2 * dis[LCA(u, v)]; } void solve() { cin >> n >> k; for(int i = 1; i < n; i ++) { int u, v, t; cin >> u >> v >> t; e[u].push_back(v); w[u].push_back(t); e[v].push_back(u); w[v].push_back(t); } dfs(1, 0); int ans = 0; for(int i = 1; i <= k; i ++) { cin >> a[i]; ans += path_dis(a[i], a[i - 1]); } for(int i = 1; i <= k; i ++) cout << ans - path_dis(a[i - 1], a[i]) - path_dis(a[i], a[i + 1]) + path_dis(a[i - 1], a[i + 1]) << ' '; } signed main() { IOS; int _ = 1; // cin >> _; while(_ --) solve(); return _ ^ _; }
试题 J: 砍树(LCA)
时间限制:
【问题描述】
给定一棵由
小明想知道是否能够选择一条树上的边砍断,使得对于每个
【输入格式】
输入共
后面
后面
【输出格式】
一行一个整数,表示答案,如有多个答案,输出编号最大的一个。
【样例输入】
6 2
1 2
2 3
4 3
2 5
6 5
3 6
4 5
【样例输出】
4
【样例说明】
断开第
断开第
【评测用例与约定】
对于
对于
点击查看代码
#include <bits/stdc++.h> #define IOS ios::sync_with_stdio(false);cin.tie(nullptr),cout.tie(nullptr) #define int long long #define fi first #define se second using namespace std; const int N = 1e5 + 10; vector<int> e[N], num[N]; int fa[N][21], dep[N], s[N]; int n, m, ans; void dfs(int u, int Fa) { dep[u] = dep[Fa] + 1; fa[u][0] = Fa; for(int i = 1; i <= 20; i ++) fa[u][i] = fa[fa[u][i - 1]][i - 1]; for(auto &v : e[u]) { if(v == Fa) continue; dfs(v, u); } } int LCA(int u, int v) { if(dep[u] < dep[v]) swap(v, u); for(int i = 20; i >= 0; i --) if(dep[fa[u][i]] >= dep[v]) u = fa[u][i]; if(u == v) return u; for(int i = 20; i >= 0; i --) if(fa[u][i] != fa[v][i]) { u = fa[u][i]; v = fa[v][i]; } return fa[u][0]; } void dfs2(int u, int Fa) { for(int i = 0; i < e[u].size(); i ++) { int v = e[u][i], p = num[u][i]; if(v == Fa) continue; dfs2(v, u); s[u] += s[v]; if(s[v] == m) ans = max(ans, p); } } void solve() { cin >> n >> m; ans = -1; for(int i = 1; i < n; i ++) { int x, y; cin >> x >> y; e[x].push_back(y); num[x].push_back(i); e[y].push_back(x); num[y].push_back(i); } dfs(1, 0); for(int i = 1; i <= m; i ++) { int a, b; cin >> a >> b; s[a] ++, s[b] ++, s[LCA(a, b)] -= 2; } dfs2(1, 0); cout << ans << '\n'; } signed main() { IOS; int _ = 1; // cin >> _; while(_ --) solve(); return _ ^ _; }
本文作者:chfychin
本文链接:https://www.cnblogs.com/chfychin/p/17756709.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步