Codeforces Round #54 C.Trees

C. Trees

题意

给定一个长度为n的数组,通过增大或修改其中的数使得数组满足如下要求,求需要修改的最少次数

  • 第一个数等于倒数第一个数,第二个数等于倒数第二个数,以此类推
  • 相邻两个数的差的绝对值为1

思路

可以发现数组中的某个数一旦确定,整个数组就都确定了下来;而我们最少可以使得一个数不被修改,即通过该数决定整个数组;由此可以比较容易地得到一个O(n^2)的解法,即遍历数组中的每一个数,我们选择不修改该数,根据这个数得到的数组,统计哪些数是需要修改的,从而得到最小修改次数

在上面的思路,我们是每次选择数组中的一个数,再去统计需要修改的数,这样就存在选择a[i]和选择a[j]生成的数组是一样的情况,而对于这种情况,我们总是会重新计算一次需要修改的数字

由于选择不修改一个数a[i],就确定了整个数组,也相当于确定了第一个数a[0]',相当于将a[0]修改为a[0]'得到的数组也等价于上述的数组,所以我们可以遍历一遍数组,预先统计所有可能的a[0]'的个数,需要修改的个数即为数组的长度减去a[0]'的个数

#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdio>
#include <unordered_map>

using namespace std;

int main() {
    // freopen("in.txt", "r", stdin);
    ios::sync_with_stdio(false);
    int n, x;
    cin >> n;
    unordered_map<int, int> mp;
    for(int i = 1; i <= n; i++) {
        cin >> x;
        if(i <= n / 2) {
        	// a[i] = a[1] + i - 1;
            mp[x - (i - 1)]++;
        } else {
        	// a[i] = a[n] + (n - i);
            mp[x - (n - i)]++;
        }
    }
    int res = n;
    for(auto it : mp) {
        if(it.first)
            res = min(res, n - it.second);
    }
    cout << res << endl;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值