根据题目 我们要选择一个长度为n的区间 令这个区间内的不重复数字最多 这一过程可以使用滑动窗口实现
cpp
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n;
cin>>n;
vector<int>a(n);
for(int i=0;i<n;i++)cin>>a[i];
auto b=a;
sort(a.begin(),a.end());
a.erase(unique(a.begin(),a.end()),a.end());
int m=a.size();
int cl=0,cr=0;
for(int r=0,l=0;r<m;r++){ //滑动窗口
while(l<r&&a[l]<=a[r]-n){ //窗口左端收缩 维护长度
++l;
}
if(cr-cl<r-l){ //更新最优窗口长度
cr=r;cl=l;
}
}//连续最优子区间的最小值(最终顺子的起始值);
int minn=a[cl];
vector<int>vis(n);
for(int i=cl;i<=cr;i++)vis[a[i]-minn]=1; //标记原始数字
vector<pair<int, int>> ans; //保存修改方案
for(int i=0,j=0;i<n;i++){//i 遍历数组中的每一个元素 j遍历vis
//j向右移动 直到vis[i]!=1 也就是第一个需要填充的位置
while(j<n&&vis[j]){
++j;
}
//判断当前原始牌b[i]是否存在最优子区间,且对应位置未被占用
if(b[i]>=minn&&b[i]<minn+n&&vis[b[i]-minn]==1){//已经存在就不变 如果有重复第一次会变为2 后面会利用
vis[b[i]-minn]=2;
}else {
ans.emplace_back(i+1,j+minn); //对于非有效 直接改变
vis[j]=2;
}
}
cout<<ans.size()<<'\n';
for(auto [i,x]:ans){
cout<<i<<' '<<x<<'\n';
}
return 0;
}