Codeforces Round 893 (Div. 2) 赛后总结

小菜鸡的赛后总结

  • B好烦,最近想刷一些低分段的games类型的题,以后好快速切掉

A. Buttons

  • 题意:有两人进行游戏。先手有 a个按钮,后手有 b个按钮。还有 c个公用的按钮。每一回合,每人必须选择一个自己的按钮或者公共按钮按下,且不能选择已经按过的按钮。无法按下按钮的人输掉游戏。给出a,b,c,求出最后的获胜者
  • 思路:两人优先争公共按钮,而对于先手来说,如果c不是偶数,那么a会用的更多一些,如果是偶数,则两人会平分公共按钮,这时候只要比对a和b的大小就行了,c是奇数的话先手就加1即可
void BlueFire()
{
    ll a, b, c;
    cin >> a >> b >> c;
 
    a = a + c + !(c%2 == 0);
    b = b + c;
    if (a > b)
        cout << "First" << endl;
    else
        cout << "Second" << endl;
    return;
}
 

B. The Walkway

  • 题意:数轴上的一些点上有一些饼干摊。现从 x=1走到 x=n,在每个点,如果下面条件至少有一个满足,则会吃一枚饼干:
    1. x=1
    2. 当前位置 - 上次吃饼干的位置 至少为 d
    3. 当前位置有饼干摊。
      现在恰好撤去任意一个饼干摊,要求使从 x=1到 x=n 路程上吃的饼干总数最少。问最少要吃多少饼干?有多少种达成最少的方案?
  • 思路:先计算出不撤也就是原本的情况下应该吃多少饼干,然后枚举撤去某个饼干摊,减去它造成的影响(即和前面最近的饼干摊距离除以d,以及后面最近的饼干摊距离除以d),再加上撤去它又应该吃多少饼干。比对答案即可
void BlueFire()
{
    int n, m, k;
    cin >> n >> m >> k;
    vector<int> v(m + 2);
    for (int i = 1; i <= m; i++)
        cin >> v[i];
    v[0] = 1, v[m + 1] = n + 1;

    ll res = 1; // 起点

    for (int i = 1; i <= m + 1; i++)
    {
        res += (v[i] - v[i - 1] - 1) / k;
        if (v[i] != 1 && v[i] != n + 1)
            res++;
    }

    // 枚举删除每一个位置
    ll ans = 1e9 + 1;
    ll fas = 0;
    for (int i = 1; i <= m; i++)
    {
        ll t = res;
        t -= (v[i] - v[i - 1] - 1) / k + (v[i + 1] - v[i] - 1) / k; // 减去有这个摊位存在时的情况
        if (v[i] != 1 && v[i] != n + 1)
            t--;                            // 减去这个摊位
        t += (v[i + 1] - v[i - 1] - 1) / k; // 新的需求

        if (t < ans)
        {
            ans = t;
            fas = 1;
        }
        else if (t == ans)
            fas++;
    }

    cout << ans << " " << fas << endl;

    return;
}

C. Yet Another Permutation Problem

  • 题意:给出一个数字 n ,定义 d 数组为 d[i] = gcd( a[i] , a[i]%n+1 ),构造一个长度为 n 的排列 a ,使得 d 数组中不同数字的个数最大
  • 思路:贪心一直枚举前一个数的两倍即可(为了使最大公因数尽可能不同)
void BlueFire()
{
    int n;
    cin >> n;
    vector<int> h(n + 1);
    for (int i = 1; i <= n; i++)
        h[i] = 0;
    cout << 1 << " ";
    h[1] = 1;
    for (int i = 1; i <= n; i++)
    {
        if (!h[i])
        {
            cout << i << " ";
            h[i] = 1;
            ll f = i * 2;
            while (f <= n && !h[f])
            {
                cout << f << " ";
                h[f] = 1;
                f *= 2;
            }
        }
    }
    cout << endl;
    return;
}
posted @ 2023-08-17 18:01  布鲁诺邦古耐夫  阅读(29)  评论(0)    收藏  举报