codeforces #433C Ryouko's Memory Note(瞎搞)

题目地址:http://codeforces.com/problemset/problem/433/C

这题实在没什么思路,思路是从网上看的。智商不能暴露太多。。。

这题的思路是把每一个数的与之相邻的保存下来,为了方便,可以用vector数组。然后为了使得距离之和最短,要取中位数。在一串数字中,距所有数字距离之和最短的就是中位数了,这点应该很好理解。然后把该值修改为该中位数,然后最后找出能使值减少的最大的就是最终要修改的值。

代码如下:

#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#include <queue>
#include <map>
#include <set>
#include <algorithm>

using namespace std;
#define LL __int64
vector<int>q[110000];
int a[110000];
int main()
{
    int n, m, i, max1=-1, len, x, j;
    LL tmp, sum=0, min1;
    scanf("%d%d",&n,&m);
    for(i=0; i<m; i++)
    {
        scanf("%d",&a[i]);
        if(i!=0&&a[i]!=a[i-1])
        {
            sum+=abs(a[i]-a[i-1]);
            q[a[i]].push_back(a[i-1]);
            q[a[i-1]].push_back(a[i]);
        }
        if(max1<a[i])
            max1=a[i];
    }
    min1=sum;
    for(i=1;i<=max1;i++)
    {
        tmp=sum;
        int len=q[i].size();
        if(len==0)
            continue ;
        sort(q[i].begin(),q[i].end());
        x=q[i][len/2];
        for(j=0;j<len;j++)
        {
            tmp+=abs(x-q[i][j])-abs(i-q[i][j]);
        }
        min1=min(tmp,min1);
    }
    printf("%I64d\n",min1);
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值