2023年第14届蓝桥杯大赛软件赛省赛 C/C++ 大学 B 组
目录
2023年第14届蓝桥杯大赛软件赛省赛 C/C++ 大学 B 组
试题:第十四届蓝桥杯大赛软件赛省赛_CB.pdf
https://www.aliyundrive.com/s/VCX3wGSUBmd
试题 A: 日期统计(5)
直接暴力,8个for + 优化。
答案:235
点击查看代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e6 + 10, INF = 0x3f3f3f3f;
int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int n = 100, a[110], st[13][33];
int main() {
freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
for (int i = 1; i <= n; i++) cin >> a[i];
for (int y1 = 1; y1 <= n-7; y1++) {
if (a[y1] != 2) continue;
for (int y2 = y1+1; y2 <= n-6; y2++) {
if (a[y2] != 0) continue;
for (int y3 = y2+1; y3 <= n-5; y3++) {
if (a[y3] != 2) continue;
for (int y4 = y3+1; y4 <= n-4; y4++) {
if (a[y4] != 3) continue;
for (int m1 = y4+1; m1 <= n-3; m1++) {
for (int m2 = m1+1; m2 <= n-2; m2++) {
int mm = a[m1] * 10 + a[m2];
if (mm < 1 || mm > 12) continue;
if(st[mm][0]==mon[mm]) continue;
for (int d1 = m2+1; d1 <= n-1; d1++) {
for (int d2 = d1+1; d2 <= n; d2++) {
int dd = a[d1] * 10 + a[d2];
if (dd >= 1 && dd <= mon[mm]) {
if(!st[mm][dd]) st[mm][0] ++;
st[mm][dd] = 1;
}
}
}
}
}
}
}
}
}
int ans = 0;
for (int i = 1; i <= 12; i++)
for (int j = 1; j <= mon[i]; j++) ans += st[i][j];
cout << ans << endl;
return 0;
}
试题 B: 01 串的熵(5)
化简公式 \(h(s) = -\sum_0^1{(t_i*p_i*log_2(p_i))}\),枚举 0 的数量,判断是否合法
答案:11027421
关于 \(log\)的求法:库中给出了
log(x); // 以常数 e为底
log10(x); // 以 10为底
log2(x); // 以 2为底
如果要求以 a 为底 b的对数:\(log_{a}(b)\),
可以利用:\(log_{a}(b)= \frac{log_c(b)}{log_c(a)} =log(b)/log(a)\)。
C++参考手册:https://zh.cppreference.com/w/cpp/numeric/math
点击查看代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e6 + 10, INF = 0x3f3f3f3f;
int main() {
int n = 23333333;
double xs = 11625907.5798;
for (int i = 0; i <= n/2; i++) {
int t0 = i, t1 = n - i;
double p0 = 1.0 * t0 / n, p1 = 1 - p0;
double s0 = -t0 * p0 * log(p0) / log(2);
double s1 = -t1 * p1 * log(p1) / log(2);
if (abs(s0 + s1 - xs) <= 1e-4) {
cout << t0;
}
}
return 0;
}
试题 C: 冶炼金属(10)
二分答案
点击查看代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e6 + 10, INF = 0x3f3f3f3f;
int n, a[N], b[N];
bool chk1(int x) {
for (int i = 1; i <= n; i++)
if (a[i] / x > b[i]) return 0;
return 1;
}
bool chk2(int x) {
for (int i = 1; i <= n; i++)
if (a[i] / x < b[i]) return 0;
return 1;
}
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; i++)
scanf("%d%d", &a[i], &b[i]);
int l = 1, r = 1e9, ans1, ans2;
while (l < r) {
int mid = l + r >> 1;
if (chk1(mid)) r = mid;
else l = mid + 1;
}
ans1 = r, l = 1, r = 1e9;
while (l < r) {
int mid = l + r + 1 >> 1;
if (chk2(mid)) l = mid;
else r = mid - 1;
}
ans2 = l;
printf("%d %d\n", ans1, ans2);
return 0;
}
试题 D: 飞机降落(10)
贪心,按照最晚下落时间点升序,下落时长降序排序,依次停放,
正确性未证明,对拍了一下,wa了。
N≤10,枚举所有排列,判断是否有合法的排列,复杂度 \(O(n!*n*t)\),
3e8的计算量大概1s,题目限制2s。
点击查看代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e6 + 10, INF = 0x3f3f3f3f;
struct T {
int t, d, l;
bool operator<(const T& r) const {
if (t + d != r.t + r.d) return t + d < r.t + r.d;
return l < r.l;
}
} t[N];
int main1() {
int T, n, a, b, c; scanf("%d", &T);
while (T--) {
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d%d%d", &a, &b, &c);
t[i] = {a, b, c};
}
sort(t + 1, t + 1 + n);
int te = t[1].t + t[1].l, f = 1;
for (int i = 2; i <= n; i++) {
if (te > t[i].t + t[i].d) { f = 0; break; }
if (te < t[i].t) te = t[i].t;
te += t[i].l;
}
printf("%s\n", f ? "YES" : "NO");
}
return 0;
}
int p[N];
int main() {
int T, n, a, b, c; scanf("%d", &T);
while (T--) {
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d%d%d", &a, &b, &c);
t[i] = {a, b, c}, p[i]=i;
}
int te=0, f=1;
do {
te=0, f=1;
for(int j=1; j<=n; j++) {
int i=p[j];
if(te > t[i].t+t[i].d) { f=0; break; }
if(te < t[i].t) te = t[i].t;
te += t[i].l;
}
if(f) break;
} while(next_permutation(p+1, p+1+n));
printf("%s\n", f ? "YES" : "NO");
}
return 0;
}
试题 E: 接龙数列(15)
dp 求出其最长接龙子序列长度 m, n-m就是答案。
- dp[i] 表示以第i个数结尾的最长接龙子序列长度
dp[i] = dp[最后出现首元素的位置]+1;
最长接龙子序列长度 m=max(dp[i])
点击查看代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e6 + 10, INF = 0x3f3f3f3f;
int n,m;
string a;
int L[N], R[N], dp[N], last[200];
int main() {
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a;
L[i] = a[0], R[i] = a[a.size() - 1];
dp[i] = dp[last[L[i]]] + 1;
if (dp[i] > dp[last[R[i]]])
last[R[i]] = i;
m = max(m, dp[i]);
}
cout << n - m;
return 0;
}
从选或不选的角度出发
- dp[i] 表示以数字 i 结尾的最长接龙子序列长度
x 表示 第 i 个数的第一个数字,y 表示第 i 个数字的最后一个数字
dp[y] = max(dp[x]+1, dp[y]); // max(选,不选)
点击查看代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e6 + 10, INF = 0x3f3f3f3f;
int n, m, dp[N];
string a;
int main() {
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a;
int x = a[0] - '0', y = a[a.size() - 1] - '0';
dp[y] = max(dp[x] + 1, dp[y]), m = max(m, dp[y]);
}
cout << n - m;
return 0;
}
试题 F: 岛屿个数(15)
连通块,环,两次bfs即可
试题 G: 子串简写(20)
后缀和求c2的个数,遍历c1,加上对应后缀和(i+k-1),复杂度 \(O(n)\)。
点击查看代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e6 + 10, INF = 0x3f3f3f3f;
int k, a[N];
string s;
char c1, c2;
int main() {
cin >> k >> s >> c1 >> c2;
for (int i = s.size() - 1; i >= 0; i--)
a[i] = a[i + 1] + (s[i] == c2);
int i = s.find(c1);
LL ans = 0;
while (i != string::npos) {
ans += a[i + k - 1];
i = s.find(c1, i + 1);
}
cout << ans;
return 0;
}
试题 H: 整数删除(20)
链表+一个可以做到排序nlogn的数据结构
试题 I: 景区导游(25)
LCA,1e5 的数据用倍增
dis[i] 表示 根节点到 i 的距离/花费。
两点(a,b)之间的花费 = \(dis[a]+dis[b]-2*dis[lca(a,b)];\)
先求出按顺序出发的总花费 s,当删除某个 A[i]时有三种情况
- \(i=1\),花费变化:减去 A[1]->A[2] 的花费;
- \(i=k\),花费变化:减去 A[k-1]->A[k] 的花费;
- \(i\in[2,k-1]\),花费变化:减去 A[i-1]->A[i],减去 A[i]->A[i+1],加上 A[i-1]->A[i+1] 的花费。
点击查看代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e6 + 10, INF = 0x3f3f3f3f;
vector<pair<int, int> > g[N];
int n, k, a[N];
LL s, dis[N], ans[N];
int q[N], depth[N], p[N][22];
bool st[N];
void bfs(int rt) {
depth[rt] = 1, q[0] = rt, st[rt] = 1;
int hh = 0, tt = 0;
while (hh <= tt) {
int u = q[hh++];
for (auto it : g[u]) {
int v = it.first, w = it.second;
if (st[v]) continue;
depth[v] = depth[u] + 1;
dis[v] = dis[u] + w;
q[++tt] = v, st[v] = 1, p[v][0] = u;
for (int k = 1; k <= 21; k++)
p[v][k] = p[p[v][k - 1]][k - 1];
}
}
}
int lca(int a, int b) {
if (depth[a] < depth[b]) swap(a, b);
for (int k = 21; k >= 0; k--)
if (depth[p[a][k]] >= depth[b]) a = p[a][k];
if (a == b) return a;
for (int k = 21; k >= 0; k--)
if (p[a][k] != p[b][k]) a = p[a][k], b = p[b][k];
return p[a][0];
}
LL dist(int a, int b) {
return dis[a] + dis[b] - 2 * dis[lca(a, b)];
}
int main() {
scanf("%d%d", &n, &k);
for (int i = 1, u, v, t; i < n; i++) {
scanf("%d%d%d", &u, &v, &t);
g[u].push_back({v, t});
g[v].push_back({u, t});
}
bfs(1);
for (int i = 1; i <= k; i++) scanf("%d", &a[i]);
for (int i = 2; i <= k; i++) s += dist(a[i - 1], a[i]);
ans[1] = s - dist(a[1], a[2]);
ans[k] = s - dist(a[k - 1], a[k]);
for (int i = 2; i < k; i++)
ans[i] = s - dist(a[i - 1], a[i]) - dist(a[i], a[i + 1])
+ dist(a[i - 1], a[i + 1]);
for (int i = 1; i <= k; i++) printf("%lld ", ans[i]);
return 0;
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 如何使用 Uni-app 实现视频聊天(源码,支持安卓、iOS)
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)