ccinfi21C 构造
C. Tug of War
题意: A队有n人,B队有m人,给定了每个人的能力值ai和bi。A队按照(a1...n)的顺序出场,获胜的人留在场上,输了的人离场,平局都立场。求B队能否获胜,如果能的话,输出字典序最小的排列。
Solution: 将B队降序排列。令p1表示A当前的人,p2表示B当前的人。用双指针找出B获胜需要的人,将剩余的人升序输出,获胜需要的人降序输出即可。
#include <bits/stdc++.h>
#define ll long long
// #define int ll
#define mp make_pair
#define fi first
#define se second
#define pb push_back
#define vi vector<int>
#define pi pair<int, int>
#define vpii vector<pi>
#define il inline
#define ri register
#define all(a) a.begin(), a.end()
#define fr(a) freopen(a, "r", stdin)
#define fo(a) freopen(a, "w", stdout);
#define mod 998244353
template<typename T> bool chkmin(T &a, T b){return (b < a) ? a = b, 1 : 0;}
template<typename T> bool chkmax(T &a, T b){return (b > a) ? a = b, 1 : 0;}
ll ksm(ll a, ll b) {if (b == 0) return 1; ll ns = ksm(a, b >> 1); ns = ns * ns % mod; if (b & 1) ns = ns * a % mod; return ns;}
using namespace std;
const int maxn = 1000005;
/**/
int n, m, a[maxn], b[maxn];
/**/
il bool cmp(int x, int y) { return x > y;}
il void solve() {
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
for(int i = 1; i <= m; i++) scanf("%d", &b[i]);
sort(b + 1, b + 1 + m, cmp);
int p1 = 1, p2 = 1, err = 0;
while(p1 <= n && p2 <= m) {
if(a[p1] > b[p2]) {
err = 1;
break;
}
else if(a[p1] < b[p2]) { ++p1;
else ++p1, ++p2;
}
if(p2 > m || err) {printf("NO\n"); return;}
printf("YES\n");
for(int i = m; i > p2; i--) cout << b[i] << ' ';
for(int i = 1; i <= p2; i++) cout << b[i] << ' ';
puts("");
}
signed main()
{
int T;
cin >> T;
while(T--) {
solve();
}
return 0;
}