一,思路:
1.因为题目限定了,数组内的元素是在 0-n之间的数(一共 n+1 个数,那么数组中必定会缺少一个 0-n之间的数)。
2.根据样例模拟很容就会发现,一个规律,每次操作其实就是将数组先前移一格(类似于滑窗,我这里是向前滑动,每次前面更新,后面淘汰)。
3.当你操作 n+1次后又回到了,起始状态(循环),那么 操作k次其实结果和操作 k%(n+1)是一样的 那么,时间复杂度就缩小到 1e5次方级别了。
4.具体实现看代码。
二,代码
#include <iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 1e5+10;
typedef long long ll;
int arr[N];
void sovle() {
int n, k;
cin >> n >> k;
//用set来求mex
set<int> s;
for (int i = 1; i <= n; i++) {
cin >> arr[i];
s.insert(arr[i]);
}
//将找到的mex放到,arr[0](跟方便后面操作)
for (int i = 0; i <= n; i++) {
if (!s.count(i)) {
arr[0] = i;
break;
}
}
//实际操作次数
int num = k % (n + 1);
//利用双指针维护窗口,这里有点类似于循环链表
int l = 1, r = n;
while (num--) {
l--, r--;
if (l < 0) l = n;
if (r < 0) r = n;
}
//l-1为了方便输出
int i = l -1;
while (true) {
//类似循环链表操做
i++;
if (i > n) i = 0;
cout << arr[i] << " ";
if (i == r) break;
}
cout << endl;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin >> t;
while (t--) {
sovle();
}
return 0;
}