蓝桥杯软件赛C++A组省赛真题训练:2024年

蓝桥杯软件赛C++A组省赛真题训练:2024年

摘要

题目 知识点
P10385 [蓝桥杯 2024 省 A] 艺术与篮球 - 洛谷 日期,模拟
P10386 [蓝桥杯 2024 省 A] 五子棋对弈 - 洛谷 模拟
P10387 [蓝桥杯 2024 省 A] 训练士兵 - 洛谷 前缀和
P10388 [蓝桥杯 2024 省 A] 团建 - 洛谷 多重DFS 求 树的最长公共路径
P10389 [蓝桥杯 2024 省 A] 成绩统计 - 洛谷 前缀和、二分答案

艺术与篮球

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include<bits/stdc++.h>
using namespace std;

int c[10] = {13, 1, 2, 3, 5, 4, 4, 2, 2, 2};
int monthDays[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int ans;

// 闰年判断
bool isLuckyYear(int y){
return (y % 400 == 0 || (y % 4 == 0 && y % 100 != 0));
}

// 得到一个月的日数
int getDay(int y, int m){
if(m == 2 && isLuckyYear(y)){
return 29;
}else{
return monthDays[m];
}
}

// 笔画数是否超过50
bool judge(int y, int m, int d){
char str[100];
sprintf(str,"%04d%02d%02d",y,m,d);
int sum = 0;
for(int i = 0 ; i < 8 ; i ++){
sum += c[(str[i] - '0')];
}
return sum > 50;
}

int main(void){
//2000 年 1 月 1 日 到 2023 年 12 月 31 日
for(int y = 2000 ; y <= 2023 ; y ++){
for(int m = 1 ; m <= 12 ; m ++){
int D = getDay(y,m);
for(int d = 1 ; d <= D ; d ++){
if(judge(y,m,d)) ans++;
}
}
}
// 2024 年 1 月 1 日 到 2024 年 4 月 13 日
for(int m = 1 ; m <= 4 ; m ++){
int D = getDay(2024, m);
if(m == 4) D = 13;
for(int d = 1 ; d <= D ; d ++){
if(judge(2024,m,d)) ans++;
}
}
cout<<ans;
return 0;
}

五子棋对弈

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include<bits/stdc++.h>
using namespace std;

int n,ans;
int a[10][10];

bool judge(){
// 易错:白/黑的比例应该是13/12
int sum = 0;
for(int i = 1 ; i <= 5 ; i ++){
for(int j = 1 ; j <= 5 ; j ++){
sum += a[i][j];
}
}
if(sum != 13) return false;
bool f;
// 行
for(int i = 1 ; i <= 5 ; i ++){
f = true; // 是否相同
for(int j = 2 ; j <= 5 ; j ++){
if(a[i][j] != a[i][j-1]){
f = false; break;
}
}
if(f) return false;
}
// 列
for(int i = 1 ; i <= 5 ; i ++){
f = true; // 是否相同
for(int j = 2 ; j <= 5 ; j ++){
if(a[j][i] != a[j-1][i]){
f = false; break;
}
}
if(f) return false;
}
// 主对角线
f = true;
for(int i = 2 ; i <= 5 ; i ++){
if(a[i][i] != a[i-1][i-1]){
f = false; break;
}
}
if(f) return false;
// 副对角线
f = true;
for(int i = 2 ; i <= 5 ; i ++){
int x = i; int y = 5 - i + 1;
if(a[x][y] != a[x-1][y+1]){
f = false;
break;
}
}
if(f) return false;
return true;
}

void dfs(int x, int y){
if(x == 5 && y == 5){
a[x][y] = 1;
if(judge()) ans++;
a[x][y] = 0;
if(judge()) ans++;
return;
}
a[x][y] = 1;
if(y < 5) dfs(x, y+1);
else dfs(x+1, 1);
a[x][y] = 0;
if(y < 5) dfs(x, y+1);
else dfs(x+1, 1);
}

int main(void){
dfs(1,1);
cout<<ans;
return 0;
}

训练士兵

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const ll maxn = 1e5 + 10;
const ll maxm = 1e6 + 10;

ll n, s, max_c;
ll p[maxn], c[maxn];
ll ans, now;
ll sum[maxm],cnt[maxm];

int main(void){
cin.tie(0), cout.tie(0);
ios::sync_with_stdio(false);
cin>>n>>s;
for(int i = 1 ; i <= n ; i ++){
cin>>p[i]>>c[i];
cnt[c[i]] += p[i]; // cnt[i] == 总共需要训练次数为i的所有士兵的代价和
max_c = max(c[i], max_c);
}
for(int i = max_c ; i >= 1 ; i --){
sum[i] = sum[i+1] + cnt[i]; // sum[i] == cnt[i]的后缀和
}
now = 1;
while(sum[now] != 0){
ans += min(s, sum[now]);
now++;
}
cout<<ans;
return 0;
}

团建

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 10;

int n,m,ans;
int a[maxn],b[maxn];
vector<int> e[maxn],d[maxn];

void dfs(int dep, int x, int y, int fx, int fy){
ans = max(dep, ans);
unordered_map<int, int> mp;
for(auto it : e[x]){
if(it != fx){
mp[a[it]] = it;
}
}
for(auto it : d[y]){
if(it != fy){
if(mp.count(b[it])){
dfs(dep+1, mp[b[it]], it, x, y);
}
}
}
}

int main(void){
cin>>n>>m;
for(int i = 1 ; i <= n ; i ++){
cin>>a[i];
}
for(int i = 1 ; i <= m ; i ++){
cin>>b[i];
}
for(int i = 1 ; i <= n-1 ; i ++){
int u,v;cin>>u>>v;
e[u].push_back(v);
e[v].push_back(u);
}
for(int i = 1 ; i <= m-1 ; i ++){
int u,v;cin>>u>>v;
d[u].push_back(v);
d[v].push_back(u);
}
if(a[1] == b[1]) dfs(1,1,1,0,0);
cout<<ans;
return 0;
}

成绩统计

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const ll maxn = 1e5 + 10;

ll n, k, t;
ll a[maxn],b[maxn],sum[maxn],sum2[maxn];

// 方差等于均方值减去均值的平方
double get_std(ll l, ll r){
double avg = 1.0*(sum[r] - sum[l-1])/k;
double avg2 = 1.0*(sum2[r] - sum2[l-1])/k;
return avg2 - avg*avg;
}

bool check(int x){
for(int i = 1 ; i <= x ; i ++){
b[i] = a[i];
}
sort(b+1, b+1+x);
for(int i = 1 ; i <= x ; i ++){
sum[i] = sum[i-1] + b[i];
sum2[i] = sum2[i-1] + b[i]*b[i];
}
for(int i = k ; i <= x ; i ++){
if(get_std(i-k+1, i) < 1.0*t){
return true;
}
}
return false;
}

int main(void){
cin>>n>>k>>t;
if(k > n){
cout<<-1; return 0;
}
for(int i = 1 ; i <= n ; i ++){
cin>>a[i];
}
ll l = k-1;
ll r = n;
ll ans = -1;
while(l+1 != r){
ll mid = (l+r)/2;
if(check(mid)){
r = mid;
ans = mid;
}else{
l = mid;
}
}
cout<<ans;
return 0;
}

蓝桥杯软件赛C++A组省赛真题训练:2024年
https://czwcugb.github.io/题解/lanqiao/2024/
作者
ChenZhiwei
发布于
2025年4月9日
许可协议