题目链接:http://codeforces.com/problemset/problem/433/C

题目意思:一本书有 n 页,每页的编号依次从 1 到 n 编排。如果从页 x 翻到页 y,那么|x-y|页都需要翻到(联系生活实际就很容易理解的了)。接着有m pieces 的 information,第 i piece 的information 在第 a[i] 页。为了减少翻页的页数,允许把某一页的信息,完全搬到某一页上,这个操作只可以执行一次。问应该把哪一页的信息搬到某一页上,从而使得翻页次数最少。

比赛的时候完全没有思路,赛后想了一段时间也是如此。于是看了tutorial,以下是链接:

http://codeforces.com/blog/entry/12397

实不相瞒,我看这个也有点...看来我的理解能力真心有问题!!!直接看了一个人的AC代码,再加上输出变量终于完全明白了。

如果大家已经看明白链接里的解题思路,那么以下内容可以忽略。

/*****************************************

首先保存每一个数左右两边与该数直接相邻的数都有哪些(注意:如果相邻的数与该数相等,就不需要保存)。假设初始序列是: 1 2 3 4 3 2 。那么如果需要保存数 3 的相邻数,就是2 4 4 2,这里用到vector操作。接着求出这些相邻数与该数之差,每一个数都这样求,得出一个和为sum,注意:这个sum 对整个序列的两两紧挨的数的差是求了两次的!!!所以代码中sum 要除以 2。 紧随着对于某一个数(x),它的相邻数进行从小到大的排序,这样是为了找出中位数。这个中位数表示对于x中的所有相邻数,离这个中位数的距离是最短的。然后再求多一次所有相邻数与这个中位数的差,再求和。每一个数都是这样求,再从这些和里面找出最少的一个就是答案。

****************************************/

别人的思路真是清晰,好佩服他们。以下是我看明白之后写的

 #include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std; #define LL long long
#define pb push_back
const int maxn = 1e5 + ;
vector<int> adj[maxn]; // adj[i]: 数值为i的数中相邻的两个不等于i的数
LL sum, ans; // sum: 每个数相邻数之差的总和; ans: 最后答案
LL adjsum[maxn], adjminsum[maxn]; // adjsum[i]:数值为i的数相邻之间的差 adjminsum[i]: 数值为i的数相邻之间的差的最小值
int a[maxn]; // 原始序列 int main()
{
int n, m;
while (scanf("%d%d", &n, &m) != EOF)
{
for (int i = ; i <= m; i++)
scanf("%d", a+i);
for (int i = ; i <= m; i++)
{
if (i != && a[i-] != a[i])
adj[a[i]].pb(a[i-]);
if (i != m && a[i+] != a[i])
adj[a[i]].pb(a[i+]);
}
sum = ;
memset(adjsum, , sizeof(adjsum));
for (int i = ; i <= n; i++)
{
if (adj[i].size())
{
sort(adj[i].begin(), adj[i].end()); // 排序以便找出中位数
for (int j = ; j < adj[i].size(); j++)
adjsum[i] += (i >= adj[i][j] ? i-adj[i][j] : adj[i][j]-i);
sum += adjsum[i];
}
}
sum /= ; // 由于每个数相邻数之差的总和算了两遍,除以2刚好只算了一次
ans = sum;
memset(adjminsum, , sizeof(adjminsum));
for (int i = ; i <= n; i++)
{
if (adj[i].size())
{
int mid = adj[i].size() / ;
for (int j = ; j < adj[i].size(); j++)
adjminsum[i] += (adj[i][mid] >= adj[i][j] ? adj[i][mid]-adj[i][j] : adj[i][j]-adj[i][mid]);
ans = min(ans, sum-adjsum[i]+adjminsum[i]);
}
}
printf("%lld\n", ans);
for (int i = ; i <= n; i++) // 清空
adj[i].clear();
}
return ;
}

codeforces 433C. Ryouko's Memory Note 解题报告的更多相关文章

  1. CodeForces 433C Ryouko's Memory Note (中位数定理)

    <题目链接> 题目大意:给你一堆数字,允许你修改所有相同的数字成为别的数字,不过只能修改一次,问你修改后序列相邻数字的距离和最小是多少. 解题分析: 首先,修改不是任意的,否则那样情况太多 ...

  2. CodeForces 433C Ryouko's Memory Note-暴力

                                             Ryouko's Memory Note Time Limit:1000MS     Memory Limit:262 ...

  3. codeforces C. Ryouko's Memory Note

    题意:给你m个数,然后你选择一个数替换成别的数,使得.最小.注意选择的那个数在这m个数与它相同的数都必须替换同样的数. 思路:用vector记录每一个数与它相邻的数,如果相同不必记录,然后遍历替换成与 ...

  4. Codeforces Round #248 (Div. 1) A. Ryouko's Memory Note 水题

    A. Ryouko's Memory Note 题目连接: http://www.codeforces.com/contest/434/problem/A Description Ryouko is ...

  5. codeforces 434A A. Ryouko's Memory Note(数学)

    题目链接: A. Ryouko's Memory Note time limit per test 1 second memory limit per test 256 megabytes input ...

  6. Codeforces Round #248 (Div. 2) C. Ryouko's Memory Note

    题目链接:http://codeforces.com/contest/433/problem/C 思路:可以想到,要把某一个数字变成他的相邻中的数字的其中一个,这样总和才会减少,于是我们可以把每个数的 ...

  7. Codeforces Round #248 (Div. 2) C. Ryouko's Memory Note (vector 替换)

    题目链接 题意:给m个数字, 这些数字都不大于 n,  sum的值为相邻两个数字 差的绝对值.求这n个数字里把一个数字 用 其中另一个数字代替以后, 最小的sum值. 分析:刚开始以为两个for 最坏 ...

  8. codeforces B. Dima and Text Messages 解题报告

    题目链接:http://codeforces.com/problemset/problem/358/B 题目意思:给出n个单词(假设为word1,word2.word3...wordn)和一句test ...

  9. codeforces C1. The Great Julya Calendar 解题报告

    题目链接:http://codeforces.com/problemset/problem/331/C1 这是第一次参加codeforces比赛(ABBYY Cup 3.0 - Finals (onl ...

随机推荐

  1. 频繁项挖掘算法Apriori和FGrowth

    一:背景介绍 最近在公司用spark的平台做了一个购物车的推荐,用到的算法主要是FGrowth算法,它是Apriori算法的升级版,算法的主要目的是找出频繁进行一起购买的商品.本文主要介绍两个算法的背 ...

  2. ubuntu下不同版本python安装pip及pip的使用

    由于ubuntu系统自带python2.7(默认)和python3.4,所以不需要自己安装python. 可以使用python -V和python3 -V查看已安装python版本. 在不同版本的py ...

  3. css3 nth-child 与 nth-of-type 的区别

    by zhangxinxu from http://www.zhangxinxu.com本文地址:http://www.zhangxinxu.com/wordpress/?p=1709 一.深呼吸,直 ...

  4. 深究Spring中Bean的生命周期

    前言 这其实是一道面试题,是我在面试百度的时候被问到的,当时没有答出来(因为自己真的很菜),后来在网上寻找答案,看到也是一头雾水,直到看到了<Spring in action>这本书,书上 ...

  5. Maven配置将war包部署到Tomcat(tomcat7-maven-plugin)

    Tomcat7/8: 提示:经过测试Tomcat7的配置和插件在Tomcat8中能正常运行 tomcat7-maven-plugin官方帮助文档:http://tomcat.apache.org/ma ...

  6. 用JS过滤Emoji表情的输入

    本文为原创,转载请注明出处: cnzt       文章:cnzt-p http://www.cnblogs.com/zt-blog/p/6773854.html 在前端页面开发过程中,总会碰到不允许 ...

  7. centos6.5编译安装gearmand Job Server(C)

    1)下载安装包: wget https://launchpad.net/gearmand/1.2/1.1.12/+download/gearmand-1.1.12.tar.gz 2)安装编译器: yu ...

  8. 391. Perfect Rectangle

    最后更新 一刷 16-Jan-2017 这个题我甚至不知道该怎么总结. 难就难在从这个题抽象出一种解法,看了别人的答案和思路= =然而没有归类总结到某种类型,这题相当于背了个题... 简单的说,除了最 ...

  9. Java笔试面试题007

    Java笔试面试题007 1.请用正則表達式匹配出QQ号(如果QQ号码为5-10位). 解答: ^ \d{5,10}$ 2.String, StringBuffer StringBuilder的差别. ...

  10. hdu5289(2015多校1)--Assignment(单调队列)

    Assignment Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total ...