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的次数有点多。可惜了。

posted @ 2025-01-28 23:01  clockleaf  阅读(64)  评论(0)    收藏  举报