Codeforces 433C #248_div1_A 中位数的应用

擦。。今天这套题好尼玛难啊,做了一个小时,连一题都没做出来,而且还没什么头绪

查了下出题人,师大附中的 14年毕业 13年拿到的国家集训队资格 保送清华

题意是 给一串序列,计算一个值,这个值是 相邻两数的距离(或者说差的绝对值)的总和,你可以改变任意一种数(即序列里所有该数字全部变成另一个数),但只能改一次,使得刚刚要求得那个值最小。

要是只改一个数,那就很简单了,但是这个题是要改一种数,序列式乱序的,所求值跟相邻数有关,所以又不能随便打乱顺序。

然后就疯狂抓头。。

后来还是看的题解

其实题目里面改变一种数其实也很好处理,把该种数的相邻的数字都给存起来,然后就是看该数字跟这些m个数(假设为m个)的距离的最小了。根据以前数轴的思想,不难得出,只要把当前该x值,变成排序过后的m个数列中的中位数即可。因为中位数的性质就是跟所有序列数的距离和最小,这个用数轴思想很容易证明。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#define LL __int64
using namespace std;
const int N = 100000+10;
int A[N];
int n,m;
int vis[N];
vector<int> v[N];
int abs(int x)
{
    if (x<0) return -x;
    else return x;
}
int main()
{
    while (scanf("%d%d",&n,&m)!=EOF)
    {
        LL ans=0;
        memset(vis,0,sizeof vis);
        for (int i=1;i<=m;i++){
          scanf("%d",&A[i]);
          if (i>1){
            if (A[i]!=A[i-1]){
                v[A[i]].push_back(A[i-1]);
                v[A[i-1]].push_back(A[i]);
            }
            ans+=(LL)abs(A[i]-A[i-1]);
          }
        }
        LL maxn=0;
        if (m>1)
        for (int i=1;i<=m;i++){
            if (vis[A[i]]) continue;
            vis[A[i]]=1;
            sort(v[A[i]].begin(),v[A[i]].end());
            int r=v[A[i]].size();
            if (r==0) continue;
            r/=2;
            int mid=v[A[i]][r];
            LL t1=0;
            LL t2=0;
            for (int j=0;j<v[A[i]].size();j++){
                t1+=(LL)abs(mid-v[A[i]][j]);
            }
            for (int j=0;j<v[A[i]].size();j++){
                t2+=(LL)abs(A[i]-v[A[i]][j]);
            }
            maxn=max(maxn,t2-t1);
        }
        ans-=maxn;
        printf("%I64d\n",ans);
    }
    return 0;
}

Codeforces 433C #248_div1_A 中位数的应用

时间: 2024-10-29 19:13:44

Codeforces 433C #248_div1_A 中位数的应用的相关文章

Codeforces 433C. Ryouko&#39;s Memory Note (中位数,瞎搞,思维)

题目链接: http://codeforces.com/problemset/problem/433/C 题意: 给你一堆数字,允许你修改相同的数字成为别的数字,也可以修改成自己,问你修改后相邻数字的距离的绝对值的和最小是多少. 思路: 首先明确一个结论,一个数轴上一些点,要求一个与他们距离之和尽量小的点,那么这个点就是这些点的中位数,即排序后位于中间的数. 这题的思路是把每一个数的与之相邻的保存下来,为了方便,可以用vector数组.然后为了使得距离之和最短,要取中位数.在一串数字中,距所有数

CodeForces 433C Ryouko&#39;s Memory Note-暴力

Ryouko's Memory Note Time Limit:1000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Submit Status Practice CodeForces 433C Description Ryouko is an extremely forgetful girl, she could even forget something that has just happened. So in

Problem - 433C - Codeforces解题报告

对于这题本人刚开始的时候的想法是:先把最大两数差的位置找到然后merge计算一个值再与一连串相同的数做merge后计算一个值比较取最大值输出:可提交后发现不对,于是本人就搜了一下正解发现原来这题的正确解题思路是:采用数学中的中位数原理,分别把某数两边相邻且不同的数存入向量容器Vector中然后排序,找到中位数计算一遍,找到计算的最大值,然后把按照输入顺序的值计算出一个总和,然后相减就是其解. 关于中位数原理本人稍微提一下: 求中位数,首先要先进行数据的排序(从小到大),然后计算中位数的序号,分数

CodeForces 710B Optimal Point on a Line (数学,求中位数)

题意:给定n个坐标,问你所有点离哪个近距离和最短. 析:中位数啊,很明显. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <string> #include <cstdlib> #include <cmath> #include <iostream> #include <cstring>

(CodeForces )540B School Marks 贪心 (中位数)

Little Vova studies programming in an elite school. Vova and his classmates are supposed to write n progress tests, for each test they will get a mark from 1 to p. Vova is very smart and he can write every test for any mark, but he doesn't want to st

【二分答案】【中位数】codeforces 394 bun

bunDescription因为体育老师很喜欢等差数列,所以他要求学生们站队必须按身高站成等差数列.但是有些班级的学生无论如何也无法排成等差数列,于是体育老师从食堂买来了两种神奇的面包.吃一个第一种面包可以使身高增 1,吃一个第二种面包可以使身高减 1.你的任务是,对于某个班级,帮助老师安排哪些同学食用多少面包.考虑到学生的身体健康,体育老师希望吃面包最多的学生吃的面包数量尽量少.Input Format第一行一个正整数 n,表示学生的数目.第二行是长度为 n 的整数序列 a, a[i]表示第

Putting Boxes Together CodeForces - 1030F (带权中位数)

#include <iostream> #include <algorithm> #include <cstdio> #include <math.h> #include <set> #include <map> #include <queue> #include <string> #include <string.h> #include <bitset> #define REP(i,a

Codeforces Round #250 (Div. 2) (ABCD题解)

比赛链接:http://codeforces.com/contest/433 A. Kitahara Haruki's Gift time limit per test:1 second memory limit per test:256 megabytes Kitahara Haruki has bought n apples for Touma Kazusa and Ogiso Setsuna. Now he wants to divide all the apples between th

codeforces C. Ryouko&#39;s Memory Note

题意:给你m个数,然后你选择一个数替换成别的数,使得.最小.注意选择的那个数在这m个数与它相同的数都必须替换同样的数. 思路:用vector记录每一个数与它相邻的数,如果相同不必记录,然后遍历替换成与它相邻的多个数的中位数之后的所有数的和取最小就可以.. 1 #include <cstdio> 2 #include <iostream> 3 #include <cstring> 4 #include <vector> 5 #include <algor