zoukankan      html  css  js  c++  java
  • Codeforces Round #658 (Div. 2) E. Mastermind

    E. Mastermind

    题目大意:

    t组输入,给你 (n,x,y) ,其中n表示有n个数,x表示答案序列和给定的序列有x个位置值相同,y表示对答案序列重新排序最多有y个位置的值相同,在给出一个大小是n的序列,问是否存在一个满足条件的答案序列,存在则输出。

    题解:

    贪心。

    • 先求出每一个颜色的数量,写一个结构体,存三个值,一个 (id),一个(pos),一个 (color)(id) 是为了之后排序打乱之后存答案,$ pos$ 表示当前这个是这个(color) 的第几个,(color) 就不用说了吧
    • 然后按照 (pos) 从大到小排个序,注意这个和 (color) 唯一的关系就是排在越前面表示这个 (color) 的值越多。
    • 为什么要这么排呢?这个是因为我们贪心的想,同一个颜色的color越少越好,这个有利于之后不同颜色的匹配,也不影响其他匹配。
    • 所以按照 (pos) 排完序之后,前面的 (x)个就用来满足第一个要求。
    • 之后就是一个比较简单的问题,如果接下来看不懂可以看看这个题目:Gym - 101291I,推荐题解:https://blog.csdn.net/qq_43305984/article/details/88749031
    • 所以接下来就是把 (pos) 表示这个 (color) 还剩下的数,然后按照 (pos) 从大到小排个序,假设有 (n) 个,第 (i) 个和第 (frac{n}{2}+i)个匹配,和上面哪个题目一样的做法。

    但是这个还是挺难写的,还有考虑一些特殊情况,比如 ((y-x)&1 \,and\, y==n) ,所以要特判。

    #include <bits/stdc++.h>
    #define inf 0x3f3f3f3f
    using namespace std;
    typedef long long ll;
    const int maxn = 1e5+10;
    struct node{
        int id,pos,color;
    }a[maxn];
    int d[maxn],ans[maxn];
    bool cmp(node a,node b){
        if(a.pos==b.pos) return a.color<b.color;
        return a.pos>b.pos;
    }
    int main() {
        int t;
        scanf("%d", &t);
        int ca=0;
        while (t--) {
            ca++;
            int n, x, y;
            scanf("%d%d%d", &n, &x, &y);
            for (int i = 1; i <= n + 1; i++) d[i] = 0;
            for (int i = 1; i <= n; i++) {
                scanf("%d", &a[i].color);
                d[a[i].color]++;
                a[i].pos = d[a[i].color];
                a[i].id = i;
            }
            sort(a + 1, a + 1 + n, cmp);
            if (x < n && 2 * (n - a[x + 1].pos - x) < y - x) printf("NO
    ");
            else {
                int f = 1;
                while (d[f]) f++;
                for (int i = 1; i <= n; i++) ans[i] = f;
                for (int i = 1; i <= x; i++) ans[a[i].id] = a[i].color, d[a[i].color]--;
                for (int i = x + 1; i <= n; i++) a[i].pos = d[a[i].color];
                sort(a + 1 + x, a + 1 + n, cmp);
                if ((y - x) % 2 && y == n) {
                    int nxt = x + 1 + a[x + 1].pos;
                    ans[a[x + 1].id] = a[nxt].color;
                    int nex = nxt + a[nxt].pos;
                    ans[a[nxt].id] = a[nex].color;
                    ans[a[nex].id] = a[x + 1].color;
                    d[a[x+1].color]--,d[a[nxt].color]--,d[a[nex].color]--;
                    for (int i = x + 1; i <= n; i++) a[i].pos = d[a[i].color];
                    a[x + 1].pos = a[nxt].pos = a[nex].pos = inf;
                    sort(a + 1 + x, a + 1 + n, cmp);
                    x += 3;
                }
    //            for(int i=1;i<=n;i++) printf("i=%d color=%d pos=%d
    ",i,a[i].color,a[i].pos);
                int mid = (x + 1 + n) / 2;
                int l = x + 1, r = max(mid + 1, x + 1 + a[x + 1].pos), res = y - x;
    //            printf("l=%d r=%d res=%d
    ",l,r,res);
                while (l <= mid && r <= n && res) {
    //                printf("res=%d l=%d id=%d color=%d r=%d id=%d color=%d
    ",res,l,a[l].id,a[l].color,r,a[r].id,a[r].color);
                    if (res) ans[a[l].id] = a[r].color, res--;
                    if (res) ans[a[r].id] = a[l].color, res--;
                    l++, r++;
                }
                printf("YES
    ");
                for (int i = 1; i <= n; i++) printf("%d ", ans[i]);
                printf("
    ");
            }
        }
    }
    /*
    1
    6 1 3
    3 1 1 1 1 1
    
    1
    6 1 6
    3 2 3 2 1 1
     */
    
  • 相关阅读:
    Educational Codeforces Round 88 (Rated for Div. 2) D. Yet Another Yet Another Task(枚举/最大连续子序列)
    Educational Codeforces Round 88 (Rated for Div. 2) A. Berland Poker(数学)
    Educational Codeforces Round 88 (Rated for Div. 2) E. Modular Stability(数论)
    Educational Codeforces Round 88 (Rated for Div. 2) C. Mixing Water(数学/二分)
    Codeforces Round #644 (Div. 3)
    Educational Codeforces Round 76 (Rated for Div. 2)
    Educational Codeforces Round 77 (Rated for Div. 2)
    Educational Codeforces Round 87 (Rated for Div. 2)
    AtCoder Beginner Contest 168
    Codeforces Round #643 (Div. 2)
  • 原文地址:https://www.cnblogs.com/EchoZQN/p/13362999.html
Copyright © 2011-2022 走看看