C. Mastermind

目录

1.Problem

2.Input

3.Output

4.Examples

4.1input

4.2output

5.Code

6.Conclusion


1.Problem

In the game of Mastermind, there are two players  — Alice and Bob. Alice has a secret code, which Bob tries to guess. Here, a code is defined as a sequence of nn colors. There are exactly n+1n+1 colors in the entire universe, numbered from 11 to n+1n+1 inclusive.

When Bob guesses a code, Alice tells him some information about how good of a guess it is, in the form of two integers xx and yy.

The first integer xx is the number of indices where Bob's guess correctly matches Alice's code. The second integer yy is the size of the intersection of the two codes as multisets. That is, if Bob were to change the order of the colors in his guess, yy is the maximum number of indices he could get correct.

For example, suppose n=5n=5, Alice's code is [3,1,6,1,2][3,1,6,1,2], and Bob's guess is [3,1,1,2,5][3,1,1,2,5]. At indices 11 and 22 colors are equal, while in the other indices they are not equal. So x=2x=2. And the two codes have the four colors 1,1,2,31,1,2,3 in common, so y=4y=4.

Solid lines denote a matched color for the same index. Dashed lines denote a matched color at a different index. xx is the number of solid lines, and yy is the total number of lines.

You are given Bob's guess and two values xx and yy. Can you find one possibility of Alice's code so that the values of xx and yy are correct?

2.Input

The first line contains a single integer tt (1≤t≤10001≤t≤1000)  — the number of test cases. Next 2t2t lines contain descriptions of test cases.

The first line of each test case contains three integers n,x,yn,x,y (1≤n≤105,0≤x≤y≤n1≤n≤105,0≤x≤y≤n)  — the length of the codes, and two values Alice responds with.

The second line of each test case contains nn integers b1,…,bnb1,…,bn (1≤bi≤n+11≤bi≤n+1)  — Bob's guess, where bibi is the ii-th color of the guess.

It is guaranteed that the sum of nn across all test cases does not exceed 105105.

3.Output

For each test case, on the first line, output "YES" if there is a solution, or "NO" if there is no possible secret code consistent with the described situation. You can print each character in any case (upper or lower).

If the answer is "YES", on the next line output nn integers a1,…,ana1,…,an (1≤ai≤n+11≤ai≤n+1)  — Alice's secret code, where aiai is the ii-th color of the code.

If there are multiple solutions, output any.

4.Examples

4.1input

7
5 2 4
3 1 1 2 5
5 3 4
1 1 2 1 2
4 0 4
5 5 3 3
4 1 4
2 3 2 3
6 1 2
3 2 1 1 1 1
6 2 4
3 3 2 1 1 1
6 2 6
1 1 3 2 1 1

4.2output

YES
3 1 6 1 2
YES
3 1 1 1 2
YES
3 3 5 5
NO
YES
4 4 4 4 3 1
YES
3 1 3 1 7 7
YES
2 3 1 1 1 1

5.Code

#include<bits/stdc++.h>

#define pb push_back
#define mp make_pair
#define fi first
#define se second

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;

int readint() {
    int x = 0, f = 1; 
    char ch = getchar();
    while (ch < '0' || ch > '9') {
        if (ch == '-') f = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9') {
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return x * f;
}

const int MAXN = 100005;

int n, x, y;
int cnt[MAXN], ans[MAXN], a[MAXN];
vector<int> v[MAXN];
set<pii> s;

void solve() {
    n = readint();
    x = readint();
    y = readint();

    for (int i = 1; i <= n + 1; i++) {
        v[i].clear();
        cnt[i] = 0;
    }

    for (int i = 1; i <= n; i++) {
        a[i] = readint();
        v[a[i]].pb(i);
        cnt[a[i]]++;
        ans[i] = 0;
    }

    s.clear();

    for (int i = 1; i <= n + 1; i++) {
        if (cnt[i]) s.insert(mp(cnt[i], i));
    }

    int knd = 0;

    for (int i = 1; i <= n + 1; i++) {
        if (!cnt[i]) {
            knd = i;
            break;
        }
    }

    for (int i = 1; i <= x; i++) {
        pii t = *(--s.end());
        s.erase(--s.end());
        ans[v[t.se].back()] = t.se;
        v[t.se].pop_back();
        t.fi--;

        if (t.fi) s.insert(t);
    }

    y -= x;
    bool fl = false;

    while (y > 1) {
        pii t1 = *(--s.end()), t2 = *s.begin();

        if (t1 == t2) {
            fl = true;
            break;
        }

        s.erase(s.find(t1));
        s.erase(s.find(t2));

        ans[v[t1.se].back()] = t2.se;
        ans[v[t2.se].back()] = t1.se;

        v[t1.se].pop_back();
        v[t2.se].pop_back();

        t1.fi--;
        t2.fi--;

        if (t1.fi) s.insert(t1);
        if (t2.fi) s.insert(t2);

        y -= 2;
    }

    if (fl) {
        printf("NO\n");
        return;
    }

    if (y == 1) {
        pii t1 = *(--s.end()), t2 = *s.begin();

        if (t1 != t2) ans[v[t1.se].back()] = t2.se;
        else {
            for (int i = 1; i <= n; i++) {
                if (ans[i] && ans[i] != t1.se && a[i] != t1.se && a[i] != ans[i]) {
                    ans[v[t1.se].back()] = t1.se;
                    swap(ans[v[t1.se].back()], ans[i]);
                    fl = true;
                    break;
                }
            }

            if (!fl) {
                printf("NO\n");
                return;
            }
        }
    }

    for (int i = 1; i <= n; i++) {
        if (!ans[i]) ans[i] = knd;
    }

    printf("YES\n");

    for (int i = 1; i <= n; i++) {
        printf("%d ", ans[i]);
    }

    printf("\n");
}

int main() {
    int T = readint();

    while (T--) {
        solve();
    }

    return 0;
}

6.Conclusion

这段C++代码实现了一个程序,该程序包含一个主函数 main 和一个辅助函数 solve。该程序的功能是处理输入数据,计算一系列数值,并输出结果。

具体而言,代码的主要部分如下:

  • 使用 C++ 的标准库头文件 #include<bits/stdc++.h>,包括了常见的标准库,简化了编程过程。
  • 定义了一些宏,如 pbmpfise,以及类型别名 typedef long long ll; 和 typedef pair<int, int> pii;
  • 实现了读取整数的函数 readint,该函数通过字符输入,将字符转换为整数。
  • 定义了常量 MAXN,表示数组的最大长度。
  • 在 solve 函数中,首先初始化一些变量和数据结构,然后通过循环读取输入数据,处理数据,最终输出结果。具体来说:
    • 通过 readint 函数读取整数 nxy
    • 使用数组和向量存储数据,对数据进行统计和处理。
    • 使用 set 存储一对整数,其中第一个整数表示出现的次数,第二个整数表示数据的值。
    • 根据输入的 x 和 y 的值,进行一系列操作,包括数据的删除、更新和替换等。
    • 最终,根据处理后的结果输出 "YES" 或 "NO" 以及相应的数值。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

向阳而生__

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值