题意:告诉你一串数,改变最少的数,使之变成连续的数(即公差为1的等差的数列)。
分析:数据量是n=50000,n^2的程序超时,一开始以为是个动规之类的,想枚举每一个数,以这个数不变,来改变其他的数,记录需要改变的数的个数。同时每个位置出现过的数标记,结果不是TLE,就是爆栈。实际上,改变最少的数,就是找到尽可能多的数使他们的值num[i]-i是一个固定值。所以,记录所有的num[i]-i,最多的那个值就是最后形成的数列中每一个Num[i]-i的值。而这个题中num[i]是10^9,所以不能用数组记num[i]-i,用vector存,然后排序,遍历一遍即可。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<iostream>
#define MAXN 50000+10
using namespace std;
int num[MAXN];
vector<int>st;
int main()
{
// freopen("in.txt","r",stdin);
int n;
while(scanf("%d",&n)!=EOF)
{
st.clear();
int maxx;
for(int i=0; i<n; i++)
{
scanf("%d",&num[i]);
int a=num[i]-i;
st.push_back(a);
}
sort(st.begin(),st.end());
int temp=st[0];
int ans=1;
maxx=ans;
int p=temp;
for(int i=1; i<(int)st.size(); i++)
{
if(st[i]==temp)
ans++;
else
{
if(maxx<ans)
{
maxx=ans;
p=temp;
}
temp=st[i];
ans=1;
}
}
if(maxx<ans)
{
maxx=ans;
p=temp;
}
printf("%d\n",n-maxx);
for(int i=0; i<n-1; i++)
printf("%d ",i+p);
printf("%d\n",p+n-1);
}
return 0;
}