牛客练习赛16 B 漂亮的树

题目链接

本来想签到抽奖,但是这个题没做出来,总感觉有思路。看了题解果然还是我想多了。

题意:给定一个数字串,将这个串前半段变成递增后半段递减,而且要求是回文串,问最少需要改动多少个数字。

题解:
常规思路枚举 a1=k a 1 = k ,然后后面依次是 a1+i a 1 + i ,但是枚举会超时。
那么对于每一个位置的 aii a i − i 是固定的的,将这些数记录下来,出现次数最多的那个就是我们可以固定的 ai a i ,那么剩下的数字也就是需要改变的。

#include
#include
#include
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);

    }
}

你可能感兴趣的:(#.#其他)