2024 CCPC Liaoning 赛后补题
https://codeforces.com/gym/105481
A 爱上字典
模拟。
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
void solve() {
string s;
getline(cin, s);
int n;
cin >> n;
map<string, bool> mp;
for (int i = 1; i <= n; ++i) {
string ss;
cin >> ss;
if (isupper(ss[0]))
ss[0] += 32;
mp[ss] = true;
}
int ans = 0;
string ss = "";
for (int i = 0; i < s.size(); ++i) {
if (isalpha(s[i]))
ss += s[i];
if (s[i] == ' ' || i == s.size() - 1) {
if (isupper(ss[0]))
ss[0] += 32;
if (!mp[ss]) {
++ans;
mp[ss] = true;
}
ss = "";
}
}
cout << ans << endl;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int _ = 1;
// cin >> _;
while (_--)
solve();
return 0;
}
B 比分幻术
https://codeforces.com/gym/105481/problem/B
翻转字符串。
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
void solve() {
int a, b;
char ch;
cin >> a >> ch >> b;
cout << b << ch << a << endl;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int _ = 1;
// cin >> _;
while (_--)
solve();
return 0;
}
C 插排串联
首先dfs搜索出所有的非叶子节点,并统计所有以当前节点为根的子树大小。对于非叶子节点的值,排序后应该是逐个少于限制后的值,并且注意根节点的权值不能超过2200。
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
void solve() {
int n;
cin >> n;
vector<long long> w(n + 1);
vector<vector<int> > e(n + 1);
w[0] = -1;
vector<int> b, node;
for (int i = 1, f; i <= n; ++i) {
cin >> f >> w[i];
e[f].push_back(i);
if (w[f] != -1) {
b.push_back(w[f]);
w[f] = -1;
node.push_back(f);
}
}
auto dfs = [&](auto self, int x) -> void {
if (w[x] != -1)
return ;
w[x] = 0;
for (auto y : e[x]) {
self(self, y);
w[x] += w[y];
}
return ;
};
dfs(dfs, 0);
if (w[0] > 2200) {
cout << "NO" << endl;
return ;
}
sort(b.begin(), b.end());
sort(node.begin(), node.end(), [&](const int &x, const int &y) {
return w[x] < w[y];
});
for (int i = 0; i < b.size(); ++i) {
if (b[i] >= w[node[i]]) continue;
cout << "NO" << endl;
return ;
}
cout << "YES" << endl;
return ;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int _ = 1;
// cin >> _;
while (_--)
solve();
return 0;
}
D 都市叠高
初看是凸包,实际是dp,直径就是某一组点对。
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
void solve() {
int n;
cin >> n;
vector<pair<int, int> > a(n + 1);
vector<double> f(n + 1);
for (int i = 1; i <= n; ++i) {
cin >> a[i].first >> a[i].second;
}
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= i; ++j) {
f[i] = max(f[i], f[j - 1] + hypot(a[i].first - a[j].first, a[i].second - a[j].second));
}
}
cout << fixed << setprecision(20) << f[n] << endl;
return ;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr); cout.tie(nullptr);
int _ = 1;
// cin >> _;
while (_--)
solve();
return 0;
}
E 俄式简餐
可以拼出来的基本图形只有1x4和2x6,按这两种类型进行长宽的特判。
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
using ll = long long;
void solve() {
int n, m, k = 0;
cin >> n >> m;
if ((n * m) % 4 != 0) {
cout << "NO" << endl;
return ;
}
if (n == 2 && m == 2) {
cout << "NO" << endl;
return ;
}
vector<vector<int> > g(n + 1, vector<int> (m + 1));
if (n % 4 == 0) {
for (int j = 1; j <= m; ++j) {
for (int i = 1; i <= n; i += 4) {
++k;
g[i][j] = g[i + 1][j] = g[i + 2][j] = g[i + 3][j] = k;
}
}
}
else if (m % 4 == 0) {
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; j += 4) {
++k;
g[i][j] = g[i][j + 1] = g[i][j + 2] = g[i][j + 3] = k;
}
}
}
else if (m > 2) {
for (int i = 1; i <= n; i += 2) {
++k;
g[i][1] = g[i][2] = g[i][3] = g[i + 1][1] = k;
++k;
g[i][4] = g[i][5] = g[i][6] = g[i + 1][6] = k;
++k;
g[i + 1][2] = g[i + 1][3] = g[i + 1][4] = g[i + 1][5] = k;
for (int j = 7; j <= m; j += 4) {
++k;
g[i][j] = g[i][j + 1] = g[i][j + 2] = g[i][j + 3] = k;
++k;
g[i + 1][j] = g[i + 1][j + 1] = g[i + 1][j + 2] = g[i + 1][j + 3] = k;
}
}
}
else if (n > 2) {
for (int j = 1; j <= m; j += 2) {
++k;
g[1][j] = g[2][j] = g[3][j] = g[1][j + 1] = k;
++k;
g[4][j] = g[5][j] = g[6][j] = g[6][j + 1] = k;
++k;
g[2][j + 1] = g[3][j + 1] = g[4][j + 1] = g[5][j + 1] = k;
for (int i = 7; i <= n; i += 4) {
++k;
g[i][j] = g[i + 1][j] = g[i + 2][j] = g[i + 3][j] = k;
++k;
g[i][j + 1] = g[i + 1][j + 1] = g[i + 2][j + 1] = g[i + 3][j + 1] = k;
}
}
}
cout << "YES" << endl;
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
cout << g[i][j] << " ";
}
cout << endl;
}
return ;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr); cout.tie(nullptr);
int _ = 1;
cin >> _;
while (_--)
solve();
return 0;
}
G 顾影自怜
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int inf = numeric_limits<int>::max();
void solve() {
int n, k; cin >> n >> k;
vector<int> a(n + 2); for(int i = 1 ; i <= n ; i ++) cin >> a[i];
a[0] = a[n + 1] = inf;
vector<int> stkl , posl(n + 1);
stkl.emplace_back(0);
for(int i = 1 ; i <= n ; i ++) {
while(!stkl.empty() && a[i] >= a[stkl.back()]) stkl.pop_back();
posl[i] = stkl.back();
stkl.emplace_back(i);
}
vector<int> stkr , posr(n + 1);
stkr.emplace_back(n + 1);
for(int i = n ; i >= 1 ; i --) {
while(!stkr.empty() && a[i] >= a[stkr.back()]) stkr.pop_back();
posr[i] = stkr.back();
stkr.emplace_back(i);
}
int ans = 0;
vector<int> last(n + 1);
vector<vector<int>> pos(n + 1);
for(int i = 1 ; i <= n ; i ++) pos[a[i]].emplace_back(i);
for(int i = 1 ; i <= n ; i ++) if(pos[a[i]].size() >= k){
int p = lower_bound(pos[a[i]].begin(),pos[a[i]].end(),i) - pos[a[i]].begin();
if(p + k - 1 >= pos[a[i]].size()) continue;
if(posr[i] > pos[a[i]][p + k - 1])
ans += (i - max(posl[i],last[a[i]])) * (posr[i] - pos[a[i]][p + k - 1]);
last[a[i]] = i;
}
cout << ans << "\n";
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr); cout.tie(nullptr);
int _ = 1;
cin >> _;
while (_--)
solve();
}
J 结课风云
签到。
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
void solve() {
int n, a, b, c;
cin >> n >> a >> b >> c;
vector<pair<int, int>> ve;
for (int i = 0; i < n; ++i) {
int x, y;
cin >> x >> y;
if (x + y >= c) continue;
ve.push_back({x, y});
}
int d;
cin >> d;
int ans = 0;
for (int i = 0; i < ve.size(); ++i) {
if (ve[i].first + d >= a)
ve[i].first = a;
else
ve[i].first += d;
if (ve[i].first + ve[i].second >= c) ++ans;
}
cout << ans << endl;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int _ = 1;
// cin >> _;
while (_--)
solve();
return 0;
}
L 龙之研习
二分,k具有单调性,算闰年容斥。
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
using ll = long long;
void solve() {
auto check = [&](ll x) -> ll {
ll s = 0, l = 4;
while (x / (l / 4) != 0) {
s += x / (l / 4);
s -= x / l;
l *= 100;
}
return s;
};
ll n;
cin >> n;
n += check(2024);
ll l = 0, r = 2e18;
while (l < r) {
ll mid = l + r >> 1;
if (check(mid) >= n)
r = mid;
else
l = mid + 1;
}
cout << l << endl;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr); cout.tie(nullptr);
int _ = 1;
cin >> _;
while (_--)
solve();
return 0;
}
总结
首先要特别感谢我的两位好队友带我拿牌子!
赛时AC了七道题,喜提银首,和金尾差一个罚时不到。L题第一发提交的上限写错了,否则真有金尾。最后一小时在G题和D题来回徘徊,G题有思路但是当时没有想到单调栈,D题是最后半小时重新看了一遍题发现不是凸包是DP,WA的次数有点多。可惜了。

浙公网安备 33010602011771号