2024ICPC昆明邀请赛个人题解

2024ICPC昆明邀请赛个人题解

题解火车头

#define _CRT_SECURE_NO_WARNINGS 1

#include <iostream>
#include <vector>
#include <algorithm>
#include <set>
#include <unordered_map>
#include <cstring>
#include <cstdio>
#include <string>
#include <queue>
#include <stack>
#include <map>
#include <list>
#include <bitset>
#include <cmath>
#include <numeric>

#define endl '\n'

#define ft first
#define sd second

#define yes cout << "yes\n"
#define no cout << "no\n"

#define Yes cout << "Yes\n"
#define No cout << "No\n"

#define YES cout << "YES\n"
#define NO cout << "NO\n"

#define pb push_back
#define eb emplace_back

#define all(x) x.begin(), x.end()
#define unq_all(x) x.erase(unique(all(x)), x.end())
#define sort_all(x) sort(all(x))
#define reverse_all(x) reverse(all(x))

#define INF 0x7fffffff
#define INFLL 0x7fffffffffffffffLL

#define RED cout << "\033[91m"
#define GREEN cout << "\033[92m"
#define YELLOW cout << "\033[93m"
#define BLUE cout << "\033[94m"
#define MAGENTA cout << "\033[95m"
#define CYAN cout << "\033[96m"
#define RESET cout << "\033[0m"

// 红色
#define DEBUG1(x)                     \
    RED;                              \
    cout << #x << " : " << x << endl; \
    RESET;

// 绿色
#define DEBUG2(x)                     \
    GREEN;                            \
    cout << #x << " : " << x << endl; \
    RESET;

// 蓝色
#define DEBUG3(x)                     \
    BLUE;                             \
    cout << #x << " : " << x << endl; \
    RESET;

// 品红
#define DEBUG4(x)                     \
    MAGENTA;                          \
    cout << #x << " : " << x << endl; \
    RESET;

// 青色
#define DEBUG5(x)                     \
    CYAN;                             \
    cout << #x << " : " << x << endl; \
    RESET;

// 黄色
#define DEBUG6(x)                     \
    YELLOW;                           \
    cout << #x << " : " << x << endl; \
    RESET;

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;

typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<ld, ld> pdd;
typedef pair<string, string> pss;
typedef pair<string, int> psi;
typedef pair<string, ll> psl;

typedef vector<bool> vb;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<string> vs;
typedef vector<pii> vpii;
typedef vector<pll> vpll;
typedef vector<pss> vpss;

typedef vector<vi> vvi;
typedef vector<vl> vvl;

typedef queue<int> qi;
typedef queue<ll> ql;
typedef queue<pii> qpii;
typedef queue<pll> qpll;
typedef queue<psi> qpsi;
typedef queue<psl> qpsl;

typedef priority_queue<int> pqi;
typedef priority_queue<ll> pql;
typedef priority_queue<string> pqs;
typedef priority_queue<pii> pqpii;
typedef priority_queue<psi> pqpsi;
typedef priority_queue<pll> pqpl;
typedef priority_queue<psi> pqpsl;

typedef map<int, int> mii;
typedef map<int, bool> mib;
typedef map<ll, ll> mll;
typedef map<ll, bool> mlb;
typedef map<char, int> mci;
typedef map<char, ll> mcl;
typedef map<char, bool> mcb;
typedef map<string, int> msi;
typedef map<string, ll> msl;
typedef map<int, bool> mib;

typedef unordered_map<int, int> umii;
typedef unordered_map<ll, ll> uml;
typedef unordered_map<char, int> umci;
typedef unordered_map<char, ll> umcl;
typedef unordered_map<string, int> umsi;
typedef unordered_map<string, ll> umsl;

template <typename T>
inline void read(T &x)
{
    T f = 1;
    x = 0;
    char ch = getchar();
    while (0 == isdigit(ch))
    {
        if (ch == '-')
            f = -1;
        ch = getchar();
    }
    while (0 != isdigit(ch))
        x = (x << 1) + (x << 3) + ch - '0', ch = getchar();
    x *= f;
}

template <typename T>
inline void write(T x)
{
    if (x < 0)
    {
        x = ~(x - 1);
        putchar('-');
    }
    if (x > 9)
        write(x / 10);
    putchar(x % 10 + '0');
}

A. Two-star Contest

题目描述

image-20240529232246219

image-20240529232343939

样例
输入
5
3 4 5
5 1 3 -1 -1
2 -1 5 -1 5
3 3 -1 -1 4
2 3 10
10000 5 0 -1
1 10 10 10
2 3 10
10 1 2 3
100 4 5 6
2 3 10
100 1 2 3
10 4 5 6
2 3 10000
100 -1 -1 -1
1 -1 -1 -1

输出
Yes
1 3 5 4
0 5 0 5
3 3 2 4
No
Yes
1 2 3
4 5 6
No
Yes
2024 5 26
11 45 14

解题思路

按星级排个序,对于每个星级贪心地维护可以允许的下限就行了。

赛时这题是队友写的,搓起来太麻烦,不想写了

B. Gold Medal

题目描述

image-20240529233343043

样例
输入
2
3 10
239 141 526
6
2 1
300 100
1000

输出
91
1400

解题思路

先计算出每场比赛还差多少只队伍就刚好多一个金牌, a i = k − a i a_i=k-a_i%k ai=kai。然后从小到大贪心的去补齐,然后再将剩余的队伍数除 k k k,加入最后答案。

题解

void solve()
{
    ll n, k;
    cin >> n >> k;
    vl a(n);
    ll ans = 0;
    for (ll i = 0; i < n; i++)
    {
        cin >> a[i];
        ans += a[i] / k;
        a[i] = k - a[i] % k;
    }
    ll m;
    cin >> m;
    sort_all(a);
    for (ll i = 0; i < n; i++)
    {
        if (a[i] <= m)
        {
            m -= a[i];
            ans++;
        }
        else
            break;
    }
    ans += m / k;
    cout << ans << endl;
}

int main()
{
    ios::sync_with_stdio(false), std::cin.tie(nullptr), std::cout.tie(nullptr);
    int _ = 1;
    std::cin >> _;
    while (_--)
    {
        solve();
    }
    return 0;
}

G. Be Positive

题目描述

image-20240529234539064

样例
输入
4
1
2
3
4

输出
impossible
1 0
1 0 2
impossible

解题思路

异或和的性质:对于 0 ∼ n 0 \sim n 0n的连续异或和,每个四个数异或和为 0 0 0。所以我们只需要对于每四个数,把它和后面的数交换一下,就可以得到最小字典序的前缀异或和不为 0 0 0的序列。这个性质的具体推导过程可以去看我武汉邀请赛的那篇题解。

注:最开头的 0 0 0 1 1 1​需要交换一下

题解

void solve()
{
    int n;
    cin >> n;
    if (n == 1 || n % 4 == 0)
    {
        cout << "impossible" << endl;
        return;
    }
    vi ans(n);
    for (int i = 0; i < n; i++)
    {
        ans[i] = i;
    }
    swap(ans[0], ans[1]);
    for (int i = 4; i < n; i += 4)
    {
        swap(ans[i], ans[i - 1]);
    }
    for (auto &x : ans)
        cout << x << " ";
    cout << endl;
}

int main()
{
    ios::sync_with_stdio(false), std::cin.tie(nullptr), std::cout.tie(nullptr);
    int _ = 1;
    std::cin >> _;
    while (_--)
    {
        solve();
    }
    return 0;
}

I. Left Shifting 2

image-20240529235614067

解题思路

无论如何我们怎么左移,最多只能让操作次数减1,所以判断那些情况操作次数可以减1就行了。

官方题解是把字符串左移直到首尾不同然后判断有没有偶数长度的连续块,有的话就对答案减1,我们赛场上的做法是分类讨论首尾是否相同的情况。

题解

void solve()
{
    string s;
    cin >> s;
    int n = s.size();
    int f = 1;
    for (int i = 1; i < n; i++)
    {
        if (s[i] == s[0])
            f++;
        else
            break;
    }
    if (f == n)
    {
        cout << n / 2 << endl;
        return;
    }
    int b = 1;
    for (int i = n - 2; i >= 0; i--)
    {
        if (s[i] == s[n - 1])
            b++;
        else
            break;
    }
    int ans = 0;
    int cnt = 1;
    int cnt2 = 0;
    for (int i = 1; i < n; i++)
    {
        if (s[i] == s[i - 1])
            cnt++;
        else
        {
            ans += cnt / 2;
            if (cnt % 2 == 0)
                cnt2++;
            cnt = 1;
        }
    }
    ans += cnt / 2;
    if (cnt % 2 == 0)
        cnt2++;
    cnt = 1;
    if (s[0] == s[n - 1])
    {
        if (f % 2 && b % 2)
            cout << ans << endl;
        else if (f % 2 == 0 && b % 2 == 0)
            cout << ans - 1 << endl;
        else
        {
            if (cnt2 > 1)
                cout << ans - 1 << endl;
            else
                cout << ans << endl;
        }
    }
    else
    {
        if (cnt2)
            cout << ans - 1 << endl;
        else
            cout << ans << endl;
    }
}

M. Italian Cuisine

题目描述

image-20240530000126949

image-20240530000146843

输入
3
5
1 1 1
0 0
1 0
5 0
3 3
0 5
6
2 4 1
2 0
4 0
6 3
4 6
2 6
0 3
4
3 3 1
3 0
6 3
3 6
0 3

输出
5
24
0

解题思路

经典的旋转卡壳问题,用双指针在图包上旋转就行

题解

typedef pair<lll, lll> P;

#define x first
#define y second

lll cross(P a, P b)
{
    return a.x * b.y - a.y * b.x;
}
lll mul(P a, P b)
{
    return a.x * b.x + a.y * b.y;
}
lll mul(P a)
{
    return a.x * a.x + a.y * a.y;
}
P del(P a, P b)
{
    return {a.x - b.x, a.y - b.y};
}

void solve()
{
    int n;
    read(n);

    P C;
    read(C.x);
    read(C.y);

    lll R;
    read(R);

    vector<P> a(n + 5);
    for (int i = 1; i <= n; i++)
    {
        read(a[i].x);
        read(a[i].y);
    }
    lll ans = 0;
    lll S = 0;
    for (int l = 1, r = l + 1; l <= n; l++)
    {
        while (1)
        {
            int rr = r % n + 1;
            lll s = cross(del(a[rr], a[l]), del(C, a[l]));
            if (s <= 0)
                break;
            if (s * s < mul(del(a[rr], a[l])) * R * R)
                break;
            S += cross(del(a[r], a[l]), del(a[rr], a[l]));
            r = rr;
        }
        ans = max(ans, S);
        int ll = l % n + 1;
        S -= cross(del(a[r], a[l]), del(a[r], a[ll]));
    }
    write(ans);
    putchar('\n');
}

int main()
{
    // ios::sync_with_stdio(false), std::cin.tie(nullptr), std::cout.tie(nullptr);
    int _ = 1;
    // std::cin >> _;
    read(_);
    while (_--)
    {
        solve();
    }
    return 0;
}
<think>嗯,用户想要找2024ICPC昆明邀请赛的题目解析,但根据提供的引用内容,现有的资料只覆盖到2022年昆明的题目,比如引用[1]提到2020、2021年的ICPC和CCPC题目,以及引用[4]详细解析了2022昆明站的G题。不过用户询问的是2024年的,这可能还没有公开的解析,或者可能还没有举办。需要先确认是否存在2024年的比赛信息,或者是否用户可能记错了年份?比如,2024年的比赛可能尚未举行,或者相关信息还未被整理发布。 首先,检查提供的引用内容,发现最新的昆明站信息是2022年的,引用[4]讨论的是2022昆明G题。用户提到的2024年可能是个错误,或者他们希望提前获取信息。但通常比赛结束后才会有解析,所以需要告知用户目前没有相关资料,并建议他们关注官方渠道或后续的社区分享。同时,可以推荐现有的2022年昆明题解作为参考,帮助用户了解题型和考点,比如动态规划、期望计算等常见问题。 另外,用户可能对如何准备比赛感兴趣,可以建议他们分析历年题目类型,比如引用[1]提到的区域赛常考题型,或者引用[3]中提到的训练经验。需要确保回答准确,避免提供不存在的资源,同时提供有用的替代信息,帮助用户找到最近的可用资料。</think>关于2024ICPC昆明邀请赛题目解析,目前尚未有官方或主流平台发布完整的题目解析报告。根据历史信息推测,ICPC区域赛的题目解析通常会在赛后由参赛队伍、算法社区或教练团队逐步整理发布。以下是可参考的备赛建议和现有资源: --- ### 一、近期ICPC题型趋势参考 1. **动态规划与组合数学** 如2022年昆明站G题考察了**概率期望与递推关系**,需掌握马尔可夫链、状态转移方程的建立[^4] $$E = \sum_{i=1}^n \left( \frac{p_i}{1-p_i} \cdot \sum_{j \neq i} \frac{p_j}{1-p_i} \right)$$ 此类问题常需分析极限状态下的数学期望。 2. **数据结构优化** 近年区域赛常出现需要**线段树/树状数组维护区间性质**的题目,例如区间最值、历史版本查询等。 3. **图论与网络流** 包括最小割建模、分层图最短路等高级技巧,如2021年沈阳站曾出现网络流与二分答案结合的题目[^2]。 --- ### 二、获取解析的途径建议 1. **官方渠道** 关注ICPC官网及昆明站承办院校的赛事公告,解析可能通过**赛后题解报告会**发布。 2. **算法社区** - **Codeforces**:搜索标签`[ICPC Kunming 2024]` - **知乎/掘金**:技术博主常撰写详细题解(例:2022年G题推导过程) 3. **训练平台** 尝试在**Codeforces Gym**或**牛客竞赛**题库中查找昆明站模拟赛题。 --- ### 三、历届昆明站真题参考 若需练习类似题型,可参考2022年昆明站题目: - **G题(豆子操作期望)**:结合概率论与递推,需推导稳定状态下的位置关系 - **B题(几何构造)**:通过坐标系变换简化多边形切割问题 ```python # 示例:概率期望计算的代码框架 def calculate_expected_value(probabilities): n = len(probabilities) expected = 0.0 for i in range(n): pi = probabilities[i] term = pi / (1 - pi) if pi != 1 else 0 sum_other = sum(pj / (1 - pi) for j, pj in enumerate(probabilities) if j != i) expected += term * sum_other return expected ``` ---
评论 6
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值