2025 CCH非专业级软件能力认证提高级第二轮总结
搬题人:帅气的cch
样例解释数量:2
正确样例解释数量:0
T2没和0取max,我不玩了😭
预期:100 + 100 + 100 + 20
实际:100 + 50 + 100 + 0
T1
签到题。
一开始看题看不懂,然后发现样例解释错了,就过了。
原题没找到,题意就是有
由题可知,编号相邻的两类会有两条连边分别连接两个点。
而这两条边总共就两种情况,第一个连第一个,第二个连第二个,或第一个连第二个,第二个连第一个。
求最小值后加入答案,最后再加上第
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int kMaxN = 1e5 + 5;
ll n, m, ans, a[kMaxN << 1], b[kMaxN << 1];
ll dis(ll a, ll b, ll c, ll d) {
return abs(a - c) + abs(b - d);
}
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++) {
cin >> a[i * 2 - 1] >> b[i * 2 - 1] >> a[i * 2] >> b[i * 2];
int nx1 = a[i * 2 - 1], ny1 = b[i * 2 - 1], nx2 = a[i * 2], ny2 = b[i * 2];
int lx1 = a[(i - 1) * 2 - 1], ly1 = b[(i - 1) * 2 - 1], lx2 = a[(i - 1) * 2], ly2 = b[(i - 1) * 2];
if (i > 1)
ans += min(dis(nx1, ny1, lx1, ly1) + dis(nx2, ny2, lx2, ly2), dis(nx1, ny1, lx2, ly2) + dis(nx2, ny2, lx1, ly1));
}
cout << ans + dis(a[n * 2 - 1], b[n * 2 - 1], a[n * 2], b[n * 2]);
return 0;
}
T2
纯最短路板子,但是我没考虑负数,没有和0取max,痛失50pts。
依旧没找到原题,题意是有
第
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int kMaxN = 2e5 + 5;
struct node {
ll to, v;
bool operator < (const node &a) const {return v > a.v;}
};
ll n, m, k, h[kMaxN], val[kMaxN], dis[kMaxN], vis[kMaxN];
vector<node> e[kMaxN];
void Dijkstra() {
memset(dis, 0x3f, sizeof(dis));
priority_queue<node> q;
q.push({1, 0});
dis[1] = 0;
while (q.size()) {
int x = q.top().to;
q.pop();
if (vis[x])
continue;
vis[x] = 1;
for (int i = 0; i < e[x].size(); i++) {
int t = e[x][i].to;
if (dis[t] > dis[x] + e[x][i].v + val[t]) {
dis[t] = dis[x] + e[x][i].v + val[t];
q.push({t, dis[t]});
}
}
}
}
int main() {
cin >> n >> m >> k;
for (int i = 1; i <= n; i++) {
cin >> h[i];
val[i] = max(0ll, h[i] - k - h[1]) * max(0ll, h[i] - k - h[1]); //这里一定要记得取max
}
for (int i = 1; i <= m; i++) {
ll x, y, z;
cin >> x >> y >> z;
e[x].push_back({y, z});
e[y].push_back({x, z});
}
Dijkstra();
cout << dis[n];
return 0;
}
T3
抽象找规律,找了2.5h。
题意就是求有多少个
对于所有的
-
若i为奇数,则
a_{i−1} < a_i ; -
若i为偶数,则
a_{i−1} > a_i 。
答案对
设
情况一
这时,答案就是把条件反过来的长度为
不难发现,把条件反过来与不反过来的答案是相同的,所以这时答案就是
情况二
设
情况三
这种情况只有
然后
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll p = 1e9 + 7;
ll n, f[10005], fact[10005], ifa[10005];
ll fpow(ll a, ll b) {
ll res = 1;
while (b) {
if (b % 2)
res = res * a % p;
a = a * a % p;
b >>= 1;
}
return res;
}
ll C(ll x, ll y) {
return fact[x] * ifa[y] % p * ifa[x - y] % p;
}
int main() {
cin >> n;
fact[0] = 1;
for (int i = 1; i <= n; i++) {
fact[i] = fact[i - 1] * i % p;
ifa[i] = fpow(fact[i], p - 2);
}
f[1] = 1;
for (ll i = 1; i <= n; i++) {
for (ll j = 2; j <= i - 1; j += 2)
f[i] = (f[j] * f[i - 1 - j] % p * C(i - 1, j) % p + f[i]) % p;
f[i] = (f[i] + f[i - 1] * (1 + (i % 2)) % p) % p;
}
cout << f[n];
return 0;
}
T4
写完T3没时间了,赶紧随便写了个20pts,然后预料之中地挂了。
总结
本次比赛出现的最大问题:时间分配不均。
我是这样打的:
前20min没看懂T1,看懂后10min过了。
然后30min把T2、3、4看了一下,然后20min写完T2。
然后开始手玩T3,玩了2h20min才发现规律,然后10min过掉。
这时才开始写T4,然后没拿到分。
所以不如先把能写暴力写了,再去过T3,能获得更高分。