题目链接:https://www.nowcoder.com/acm/contest/84/B
这道题我第一次写的时候,我的想法是正着去模拟遍历最小的变动次数,最后没写出来,好像这个思路不太对。正确的方法是反向去思考,我们先得到一个初始化为题目要求的pre数组,为了解释的清楚一点(这里描述的和代码不太一样),在ans数组里输入n个数,然后我们需要求出对应的第i个数的ans[i] - pre[i]的差值的个数,然后求出这些差值的最大值,就表示不需要变动的值的个数,然后用n减去这个最大值就是最小需要变化的个数。
AC代码:
#include
#include
#include
using namespace std;
int pre[100005];
int ans[250005];
int n;
int main()
{
scanf("%d",&n);
int t = n / 2;
if(n % 2)t++;
for(int i=1;i<=t;i++){
pre[i] = pre[n-i+1] = i;
}
int sum = -1;
int x;
memset(ans,0,sizeof(ans));
for(int i=1;i<=n;i++){
scanf("%d",&x);
int p = pre[i] - x;
ans[p + 100000]++; // 加100000是为了防止负值的出现
}
for(int i=0;i<=200005;i++){
sum = max(sum,ans[i]);
}
printf("%d\n",n - sum);
return 0;
}