2024 睿抗机器人开发者大赛CAIP-编程技能赛-本科组(省赛)
写在前面
代码需要手动展开!!!
比赛前,好久没有刷题,一直准备期末考试
比赛前一天才刚到家
15号中午匆匆忙忙的开始比赛
2点开始的时候,oms服务器直接崩了,本来以为是当时打GPLT时安装的oms版本不兼容CAIP
心想,这不开局就寄了
还好是都崩了,不是我自己的问题
第一个小时
T1,T2,T3都很快写完
看到T4后,感觉是个hard题就先跳了
T5,刚开始想的是贪心,后来发现不太对,不能直接排序后就计算,就先写了一个dfs,拿了一部分分,然后发现是个01背包,改成贪心排序+dp就过了
第二个小时
写了一个小时的T4
刚开始想的是无向图的双连通分量,但是模板已经忘了
画了画样例的图,发现用dfs+时间戳貌似可以解决
结果调了半个小时,还有最好两分钟的时候才A了
最后一分钟,服务器再次崩溃,但凡晚交一会儿,都AK不了
总结:这次CAIP发挥的还不错,名次最低也才400名
T1
输入样例:
15 3
33 35 34 36 37 40 32 31 30 29 28 29 33 38 40
输出样例:
5 1
直接遍历一下天数,判断每天的温度和周几
点击查看代码
#include<bits/stdc++.h>
#define all(x) (x).begin(), (x).end()
#define fi first
#define se second
#define lowbit(x) (x) & (-x)
using i64 = long long;
using pii = std::pair<int, int>;
void solve()
{
int n, w;
std::cin >> n >> w;
int c1 = 0, c2 = 0;
for (int i = 0; i < n; i ++) {
int x;
std::cin >> x;
if (x >= 35) {
if (w == 4) {
c2 ++;
}
else {
c1 ++;
}
}
w = (w + 1) % 7;
if (w == 0) {
w = 7;
}
}
std::cout << c1 << ' ' << c2 << '\n';
}
int main()
{
std::cin.tie(nullptr);
std::cout.tie(nullptr);
std::ios::sync_with_stdio(false);
int T = 1;
//std::cin >> T;
while (T --) solve();
return 0;
}
T2
输入样例:
3
6 2
7 3
11 5
10 1
2 9
5 8
14 3
4 3
1 6
18 1
12 1
20 0
13 0
3 2
16 4
8 1
19 0
9 4
17 1
15 0
8 2
19 1
12 2
1 9
10 1
7 5
18 0
14 0
5 2
4 4
2 5
6 2
16 3
13 1
20 0
3 7
9 3
15 0
17 5
11 3
18 0
5 2
2 9
9 4
4 7
10 3
16 0
1 6
20 0
15 1
6 0
3 6
14 3
7 4
19 0
17 0
8 9
11 0
13 5
12 0
输出样例:
1 9
2 13
3 27
4 30
5 33
6 25
7 4
8 27
9 24
10 12
11 19
12 18
13 8
14 18
15 4
16 17
17 16
18 8
19 12
20 6
按给出的排名分和杀敌数,算一下每队每场的分数,累加起来,输出即可
点击查看代码
#include<bits/stdc++.h>
#define all(x) (x).begin(), (x).end()
#define fi first
#define se second
#define lowbit(x) (x) & (-x)
using i64 = long long;
using pii = std::pair<int, int>;
int p[21] = {0, 12, 9, 7, 5, 4, 3, 3, 2, 2, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0};
void solve()
{
std::vector<int> a(20);
int n;
std::cin >> n;
while (n --) {
for (int i = 0; i < 20; i ++) {
int x, v;
std::cin >> x >> v;
a[i] += p[x] + v;
}
}
for (int i = 0; i < 20; i ++) {
std::cout << i + 1 << ' ' << a[i] << '\n';
}
}
int main()
{
std::cin.tie(nullptr);
std::cout.tie(nullptr);
std::ios::sync_with_stdio(false);
int T = 1;
//std::cin >> T;
while (T --) solve();
return 0;
}
T3
输入样例:
6 8
wm....mw
.w..ww..
..wm.wwm
w.w....w
.m.c.m..
w.....w.
输出样例:
2 7
3 5
4 6
4 7
暴力枚举即可
先判断所有温暖的水豚,谁可能挡住暖炉
若有可能挡住暖炉的水豚,判断周边的空地,哪些可以放置
最后将答案直接输出即可,注意若没有可以放置的空地,就输出”Too cold!"
点击查看代码
#include<bits/stdc++.h>
#define all(x) (x).begin(), (x).end()
#define fi first
#define se second
#define lowbit(x) (x) & (-x)
using i64 = long long;
using pii = std::pair<int, int>;
void solve()
{
int n, m;
std::cin >> n >> m;
std::vector<std::string> g(n);
for (int i = 0; i < n; i ++) {
std::cin >> g[i];
}
int nx = -1, ny = -1;
auto check1 = [&](int x, int y) -> bool {
for (int i = -1; i <= 1; i ++) {
for (int j = -1; j <= 1; j ++) {
if (i == 0 && j == 0) {
continue;
}
int a = x + i;
int b = y + j;
if (a < 0 || a >= n || b < 0 || b >= m) {
continue;
}
if (g[a][b] == 'm') {
return false;
}
}
}
return true;
};
for (int i = 0; i < n; i ++) {
for (int j = 0; j < n; j ++) {
if (g[i][j] == 'w' && check1(i, j)) {
nx = i;
ny = j;
}
}
}
if (nx == -1 && ny == -1) {
std::cout << "Too cold!\n";
}
else {
auto check2 = [&](int x, int y) -> bool {
for (int i = -1; i <= 1; i ++) {
for (int j = -1; j <= 1; j ++) {
if (i == 0 && j == 0) {
continue;
}
int a = x + i;
int b = y + j;
if (a < 0 || a >= n || b < 0 || b >= m) {
continue;
}
if (g[a][b] == 'c') {
return false;
}
}
}
return true;
};
std::vector<pii> ans;
for (int i = -1; i <= 1; i ++) {
for (int j = -1; j <= 1; j ++) {
if (i == 0 && j == 0) {
continue;
}
int a = nx + i;
int b = ny + j;
if (a < 0 || a >= n || b < 0 || b >= m) {
continue;
}
if (g[a][b] == '.') {
if (check2(a, b)) {
ans.push_back({a, b});
}
}
}
}
std::sort(all(ans));
if (ans.size() == 0) {
std::cout << "Too cold!\n";
}
else {
for (auto [x, y] : ans) {
std::cout << x + 1 << ' ' << y + 1 << '\n';
}
}
}
}
int main()
{
std::cin.tie(nullptr);
std::cout.tie(nullptr);
std::ios::sync_with_stdio(false);
int T = 1;
//std::cin >> T;
while (T --) solve();
return 0;
}
T4
输入样例:
3
10 10
1 3
3 5
5 7
7 9
1 2
2 4
2 6
3 8
9 10
1 9
10 10
1 3
3 5
5 7
7 9
9 1
1 2
2 4
4 8
8 10
10 1
10 10
1 3
3 5
5 7
7 9
9 1
2 4
4 8
8 10
10 2
10 6
输出样例:
Yes 5
No 0
No 2
画一画样例,可以发现先用dfs+时间戳
找到每个子图一共有几个环
若只有一个章鱼子图,然后从这个子图的任意节点进行dfs,统计前驱节点数量
成环时,进行相减,即可算出环中节点数量。
点击查看代码
#include<bits/stdc++.h>
#define all(x) (x).begin(), (x).end()
#define fi first
#define se second
#define lowbit(x) (x) & (-x)
using i64 = long long;
using pii = std::pair<int, int>;
void solve()
{
int n, m;
std::cin >> n >> m;
std::vector<std::vector<int>> adj(n);
for (int i = 0; i < m; i ++) {
int u, v;
std::cin >> u >> v;
u --;
v --;
adj[u].push_back(v);
adj[v].push_back(u);
}
int cnt1 = 0;
int root = -1;
int time = 0;
std::vector<int> st(n);
std::vector<int> dfn(n, -1);
auto dfs1 = [&](auto dfs1, int u, int fa) -> void {
if (st[u]) {
return;
}
// std::cerr << u << '\n';
st[u] = true;
dfn[u] = time ++;
for (auto v : adj[u]) {
if (v == fa) {
continue;
}
if (dfn[v] != -1 && dfn[v] < dfn[u]) {
cnt1 ++;
continue;
}
dfs1(dfs1, v, u);
}
};
int cnt = 0;
for (int i = 0; i < n; i ++) {
if (st[i]) {
continue;
}
dfs1(dfs1, i, -1);
// std::cerr << '\n';
// std::cerr << i << ' ' << cnt1 << '\n';
if (cnt1 == 1) {
cnt ++;
root = i;
}
cnt1 = 0;
}
if (cnt == 1) {
std::vector<int> ct(n);
std::vector<int> st2(n);
int cnt2 = 0;
ct[root] = 1;
auto dfs2 = [&](auto dfs2, int u, int fa) -> void {
if (st2[u]) {
return;
}
st2[u] = true;
for (auto v : adj[u]) {
if (v == fa) {
continue;
}
if (dfn[v] < dfn[u]) {
cnt2 = ct[u] - ct[v] + 1;
}
ct[v] = ct[u] + 1;
dfs2(dfs2, v, u);
}
};
dfs2(dfs2, root, -1);
std::cout << "Yes " << cnt2 << '\n';
}
else {
std::cout << "No " << cnt << '\n';
}
}
int main()
{
std::cin.tie(nullptr);
std::cout.tie(nullptr);
std::ios::sync_with_stdio(false);
int T = 1;
std::cin >> T;
while (T --) solve();
return 0;
}
T5
输入样例:
3
5
1 2 50
3 3 100
1 5 1
3 2 5000
4 5 30
5
1 2 50
3 3 20
1 5 1
3 2 5000
4 5 30
5
1 2 50
3 3 100
1 5 1
3 2 5000
5 5 800
输出样例:
101
80
800
先根据截止时间,再根据所需时长,最后根据价值进行贪心排序
然后再进行01背包,即可得到答案
点击查看代码
#include<bits/stdc++.h>
#define all(x) (x).begin(), (x).end()
#define fi first
#define se second
#define lowbit(x) (x) & (-x)
using i64 = long long;
using pii = std::pair<int, int>;
struct T5
{
int t, d, p;
};
void solve()
{
int n;
std::cin >> n;
std::vector<T5> a;
for (int i = 0; i < n; i ++) {
int t, d, p;
std::cin >> t >> d >> p;
if (t > d) {
continue;
}
a.push_back({t, d, p});
}
n = a.size();
std::sort(all(a), [&](T5 x, T5 y){
if (x.d != y.d) {
return x.d < y.d;
}
if (x.t != y.t) {
return x.t < y.t;
}
return x.p > y.p;
});
std::vector<int> f(5010);
for (int i = 0; i < n; i ++) {
auto [t, d, p] = a[i];
for (int T = d; T >= t; T --) {
f[T] = std::max(f[T], f[T - t] + p);
}
}
int max = 0;
for (int i = 0; i <= 5000; i ++) {
max = std::max(max, f[i]);
}
std::cout << max << '\n';
}
int main()
{
std::cin.tie(nullptr);
std::cout.tie(nullptr);
std::ios::sync_with_stdio(false);
int T = 1;
std::cin >> T;
while (T --) solve();
return 0;
}