Fence Painting
题意
按顺序使用 c c c 数组中的元素 将 a a a 数组 变成 b b b 数组 问是否可能,若可能 输出 c c c 中每个元素应该放在 a a a 中的哪个位置
思路
先找到哪些元素需要修改 存在 q q q 里
对于 c c c 中最后一个元素 c [ m ] c[m] c[m] 有以下三种情况
1.需要修改的数中有 c [ m ] c[m] c[m]
2.需要修改的数中没有 c [ m ] c[m] c[m] 但是不需要修改的数中有 c [ m ] c[m] c[m]
3. b b b 中没有 c [ m ] c[m] c[m]
用 l a s las las 表示 c [ m ] c[m] c[m] 应该修改 b b b 中的哪一个数字的下标
对于 1 直接令 l a s = q [ c [ m ] ] . b a c k ( ) las = q[c[m]].back() las=q[c[m]].back() 即可
对于 2 在 b b b 中找到一个 c [ m ] c[m] c[m] 对应的下标即可
对于 3 肯定无解 因为 c [ m ] c[m] c[m] 是最后一个修改的
对于1、2 按顺序遍历 c c c 在 q q q 中找到应该修改哪个位置 如果存在 c [ i ] c[i] c[i] 不在 q q q 中 那么直接让他先修改 c c c 中最后一个数需要修改的位置 即 l a s las las 反正最后会被覆盖
然后遍历判断一下 q q q 中改被修改的数是否都被修改了 最后输出答案即可
代码
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define mod 998244353
#define endl '\n'
using namespace std;
typedef long long LL;
typedef pair<int, int>PII;
const int N = 100100;
int n, m;
int a[N], b[N], c[N]; // a -> b by c
vector<int>q[N];
void solve() {
cin >> n >> m;
for (int i = 1; i <= n; ++i)q[i].clear();
for (int i = 1; i <= n; ++i)scanf("%d", a + i);
for (int i = 1; i <= n; ++i) {
scanf("%d", b + i);
if (b[i] != a[i]) {
q[b[i]].push_back(i); //找到每一个颜色需要修改的位置
}
}
for (int i = 1; i <= m; ++i)scanf("%d", c + i);
int las = -1;
if (q[c[m]].size()) {
las = q[c[m]].back();
q[c[m]].pop_back();
}
else {
for (int i = 1; i <= n; ++i) {
if (b[i] == c[m]) {
las = i;
break;
}
}
}
if (las == -1) {
puts("NO");
return;
}
vector<int>res(m);
res[m - 1] = las;
for (int i = 1; i < m; ++i) {
if (q[c[i]].size()) {
res[i - 1] = q[c[i]].back();
q[c[i]].pop_back();
}
else res[i - 1] = las;
}
for (int i = 1; i <= n; ++i) {
if (q[i].size()) {
puts("NO");
return;
}
}
puts("YES");
for (int i = 1; i <= m; ++i) {
printf("%d%c", res[i - 1], i == m ? '\n' : ' ');
}
}
int main() {
int t; cin >> t;
while (t--)
solve();
return 0;
}