3775. 数组补全
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int M = 200050;
int t;
int a[M];
bool f[M];
vector<int> v1, v2;
int main() {
cin >> t;
while (t--) {
memset(f, false, sizeof(f));
memset(a, 0, sizeof(a));
v1.clear();
v2.clear();
a[0] = -1;
int n;
scanf("%d", &n);
for (int i = 1; i <= n; ++i) {
scanf("%d", &a[i]);
f[a[i]] = true;
}
for (int i = 1; i <= n; ++i) {
if (f[i] == false)
v2.push_back(i);
if (f[i] == false && a[i] == 0) {
v1.push_back(i);
}
}
if (v1.size() > 1) {
for (int i = 0; i < v1.size() - 1; ++i) {
a[v1[i]] = v1[i + 1];
f[v1[i + 1]] = true;
}
a[v1[v1.size() - 1]] = v1[0];
f[v1[0]] = true;
} else if (v1.size() == 1) {
for (int i = 0; i < v2.size(); ++i) {
if (v2[i] != v1[0]) {
a[v1[0]] = v2[i];
f[v2[i]] = true;
break;
}
}
}
int j = 0;
for (int i = 1; i <= n; ++i) {
if (a[i])
cout << a[i] << " ";
else {
while (f[v2[j]])
j++;
cout << v2[j++] << " ";
}
}
cout << endl;
}
return 0;
}
用f数组记录那些数字没被用过,v1记录可能会数字i放在a[i]的情况,v2记录所有还未被填充的数字。如果v1超过一个数字的话,就让同类型的数据都往后移动一个位置,这样可以保证各不会出现在i放在a[i]上面;如果恰好只有一个数字,那就随便找一个其他数字填充进去。最后就把剩余未被用过的数字依次填充即可。