数组补全
本题题意是有一个长度为n的数组,其中的数字也是从1到n.并且数组的每一个
下标
与其对应的值
不等
但是现在有一部分不见了,需要我们填满这个数组
思路
我们可以先找到可以填上去的位置的下标`board` 以及 所有可以选择的数字, 可以选择的数字我们可以分为两种,
一种是在board中有与其相对应的,记为`limit`,//即我们需要有限制的去填写,因为题目中要求值和下标不等
一种是没有与其相对应的,记为`yep`
`我们在判断这个的时候,可以用map标记一下`
`1`如果有,我们可以在输出的的时候错序输出,
即 如果里面的数字是 2 和 3,就代表数组的第2个和第3个是需要被填的,
以及2 和 3 也是可以填进数组中的数字,那么我们 可以在第2个空中填入3,第3个空中填入2
`2`如果没有,我们就可以在数组的空白的地方按顺序输出yep中的数字
```
有一种特殊情况,就是limit中只有一个数字,这个时候我们就不可以错序输出了,这个时候我们可以在limit
的那个空白处输出yep的第一个,`yep`对应的空白处从第二个开始按顺序输出,记得最后一个yep的要输出limit的
代码
#include <bits/stdc++.h>
#define x first
#define y second
#define pb push_back
//#define int long long
#define N 200010
#define endl '\n'
#define debug cout << "fuck" <<endl;
#define ios ios::sync_with_stdio(false); cin.tie(0), cout.tie(0)
using namespace std;
const int INF = 0x3f3f3f3f;
typedef pair<int, int> PII ;
bool st[N];
void solve() {
int n;
scanf("%d", &n);
memset(st, 0, sizeof st[0] * (n + 1));
vector<int> a(n + 1), yep, board, limit;
unordered_map<int, bool> mp;
for(int i = 1; i <= n; i ++ ) {
scanf("%d", &a[i]);
if(!a[i]) board.pb(i);// kong ge
st[a[i]] = 1;
}
for(int i = 1; i <= n; i ++ ) {
if(!st[i]) { // ke yi shi yong de shu zi
if(!a[i]) {
mp[i] = 1;
limit.pb(i);
}
else {
yep.pb(i);
}
}
}
int len = limit.size();
if(len == 1 ) {
int idx = 0;
idx ++;
int len1 = yep.size();
for(int i = 1; i <= n; i ++ ) {
if(a[i]) printf("%d ", a[i]);
else {
if(mp[i]) {
printf("%d ", yep[0]);
}
else {
if(idx == len1 ) {
printf("%d ", limit[0]);
}
else
printf("%d ", yep[idx ++ ]);
}
}
}
puts("");
return;
}
int idx = 0;
int l = 0;
for(int i = 1; i <= n; i ++ ) {
if(a[i]) printf("%d ", a[i]);
else {
if(!mp[i]) {
printf("%d ", yep[idx ++]);
}
else {
if(l != len - 1) {
printf("%d ", limit[++ l]);
}
else {
printf("%d ", limit[0]);
}
}
}
}
puts("");
}
signed main()
{
int t;
cin >> t;
while(t -- ) {
solve();
}
return 0;
}
orz