本来想签到抽奖,但是这个题没做出来,总感觉有思路。看了题解果然还是我想多了。
题意:给定一个数字串,将这个串前半段变成递增后半段递减,而且要求是回文串,问最少需要改动多少个数字。
题解:
常规思路枚举
a1=k
a
1
=
k
,然后后面依次是
a1+i
a
1
+
i
,但是枚举会超时。
那么对于每一个位置的
ai−i
a
i
−
i
是固定的的,将这些数记录下来,出现次数最多的那个就是我们可以固定的
ai
a
i
,那么剩下的数字也就是需要改变的。
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int mod = 1e5;
const int N = 100005;
int cnt[2 * N],num[N],n;
int main()
{
while(~scanf("%d",&n))
{
memset(num,0,sizeof num);
memset(cnt,0,sizeof cnt);
for (int i = 1; i <= n; i++)
{
scanf("%d",&num[i]);
}
int mid = (n + 1)>>1;
for (int i = 1; i <= mid; i++)
{
cnt[num[i] - i + mod]++;
}
for (int i = mid + 1; i <= n; i++)
{
cnt[num[i] - (n - i + 1) + mod]++;
}
int ans = 0;
for (int i = 1; i <= 2 * mod; i++)
{
ans = max(ans,cnt[i]);
}
printf("%d\n",n - ans);
}
}