题目描述

codeJan 非常喜欢旅行。现在有 n 个城市排在一条线上,并且 codeJan 的位置不和任何一个城市的位置重叠。
codeJan 想要游览 m 个城市,同时因为时间是不断变化的,游览一个城市多次也是允许的,但是不能永远待在一个城市,否则那样太无聊了。给出这些城市的位置,codeJan 想要知道游览 m 个城市至少需要走多少米?

输入描述:

第一行是一个T≤20代表测试组数。
每组第一行是三个正整数n,m,p,分别代表城市数量、codeJan想要浏览的城市数量和codeJan当前的位置(单位为米)。
第二行包含n个正整数pos[i]表示第i个城市的位置,单位为米。
输入保证pos[i]<pos[i+1](i∈[1,n−1]),并且p ≠ pos[i](i∈[1,n])。

输出描述:

对于每组输入数据输出一个正整数表示 codeJan 至少需要走的距离。
示例1

输入

3
2 2 2
1 3
2 2 1
2 3
4 3 4
1 3 5 6

输出

3
2
3

说明

对于第一个样例的坐标最优移动顺序可以是:2→3→1,移动距离一共是3。
对于第二个样例的坐标最优移动顺序可以是:1→2→3,移动距离一共是2。
对于第三个样例的坐标最优移动顺序可以是:4→5→6→5,移动距离一共是3。

备注:

2≤n≤105,1≤m≤105 ,1≤p,pos[i]≤109。

题解

想法题。

最优答案来自于以下几种情况,取个最小值即可。

往右走,走到某点后在两点之间徘徊
往左走, 走到某点后在两点之间徘徊
往左一步,再往右走,走到某点后在两点之间徘徊
往右一步,在往左走,走到某点后在两点之间徘徊
在$p$左右两个城市之间徘徊

#include <bits/stdc++.h>
using namespace std; const int maxn = 1000000 + 10;
int T, n, m;
long long p;
long long a[maxn]; int main() {
scanf("%d", &T);
while(T --) {
long long ans = 1e18;
scanf("%d%d%lld", &n, &m, &p);
for(int i = 1; i <= n; i ++) {
scanf("%lld", &a[i]);
}
n ++;
a[n] = p;
sort(a + 1, a + n + 1);
int location;
for(int i = 1; i <= n; i ++) {
if(a[i] == p) location = i;
} if(location > 1) {
long long sum = 0;
int num = 0;
for(int i = location - 1; i >= 1; i --) {
long long dis = a[i + 1] - a[i];
sum = sum + dis;
num ++;
if(num > m) break;
if(i != location - 1) {
ans = min(ans, sum + 1LL * dis * (m - num));
}
}
} if(location < n) {
long long sum = 0;
int num = 0;
for(int i = location + 1; i <= n; i ++) {
long long dis = a[i] - a[i - 1];
sum = sum + dis;
num ++;
if(num > m) break;
if(i != location + 1) {
ans = min(ans, sum + 1LL * dis * (m - num));
}
}
} if(location > 1 && location < n) {
ans = min(ans, min(a[location] - a[location - 1], a[location + 1] - a[location]) + 1LL * (m - 1) * (a[location + 1] - a[location - 1])); long long sum = (a[location + 1] - a[location]) * 2;
int num = 1;
for(int i = location - 1; i >= 1; i --) {
long long dis = a[i + 1] - a[i];
sum = sum + dis;
num ++;
if(num > m) break;
if(i != location - 1) {
ans = min(ans, sum + 1LL * dis * (m - num));
}
} sum = (a[location] - a[location - 1]) * 2;
num = 1;
for(int i = location + 1; i <= n; i ++) {
long long dis = a[i] - a[i - 1];
sum = sum + dis;
num ++;
if(num > m) break;
if(i != location + 1) {
ans = min(ans, sum + 1LL * dis * (m - num));
}
} } printf("%lld\n", ans);
}
return 0;
}

Wannafly挑战赛7 B - codeJan与旅行的更多相关文章

  1. Wannafly挑战赛7 D - codeJan与青蛙

    codeJan喜欢观察世界.有一天,codeJan发现一个非常奇怪的现象.有一些年轻的青蛙聚集在一条直线上的某些位置上,同一个位置可能有多个青蛙.这些青蛙每次只会向前跳一米,并且每只青蛙每跳一次都会发 ...

  2. 【Wannafly挑战赛24E】旅行

    [Wannafly挑战赛24E]旅行 题面 牛客 题解 首先有一个非常显然的\(dp\):我们直接把\(s\rightarrow t\)的路径抠出来然后设\(f_{i,j}\)表示到第\(i\)个点, ...

  3. Wannafly挑战赛25游记

    Wannafly挑战赛25游记 A - 因子 题目大意: 令\(x=n!(n\le10^{12})\),给定一大于\(1\)的正整数\(p(p\le10000)\)求一个\(k\)使得\(p^k|x\ ...

  4. Wannafly挑战赛27

    Wannafly挑战赛27 我打的第一场$Wannafly$是第25场,$T2$竟然出了一个几何题?而且还把我好不容易升上绿的$Rating$又降回了蓝名...之后再不敢打$Wannafly$了. 由 ...

  5. Wannafly 挑战赛 19 参考题解

    这一次的 Wannafly 挑战赛题目是我出的,除了第一题,剩余的题目好像对大部分算法竞赛者来说好像都不是特别友好,但是个人感觉题目质量还是过得去的,下面是题目链接以及题解. [题目链接] Wanna ...

  6. Wannafly挑战赛21A

    题目链接 Wannafly挑战赛21A 题解 代码 #include <cstdio> #include <cmath> #define MAX 1000005 #define ...

  7. Wannafly挑战赛24游记

    Wannafly挑战赛24游记 A - 石子游戏 题目大意: A和B两人玩游戏,总共有\(n(n\le10^4)\)堆石子,轮流进行一些操作,不能进行下去的人则输掉这局游戏.操作包含以下两种: 把石子 ...

  8. Wannafly挑战赛25C 期望操作数

    Wannafly挑战赛25C 期望操作数 简单题啦 \(f[i]=\frac{\sum_{j<=i}f[j]}{i}+1\) \(f[i]=\frac{f[i]}{i}+\frac{\sum_{ ...

  9. Wannafly挑战赛18B 随机数

    Wannafly挑战赛18B 随机数 设\(f_i\)表示生成\(i\)个数有奇数个1的概率. 那么显而易见的递推式:\(f_i=p(1-f_{i-1})+(1-p)f_{i-1}=(1-2p)f_{ ...

随机推荐

  1. OpenCV---模糊操作

    推文:图像平滑处理(归一化块滤波.高斯滤波.中值滤波.双边滤波) 推文:图像的平滑与滤波 模糊操作 三种模糊操作方式 均值模糊 中值模糊 自定义模糊(可以实现上面两种模糊方式) 原理: 图像处理:基础 ...

  2. 跟我一起写Makefile(七)

    make 的运行—————— 一般来说,最简单的就是直接在命令行下输入make命令,make命令会找当前目录的makefile来执行,一切都是自动的.但也有时你也许只想让make重编译某些文件,而不是 ...

  3. 区间->点,点->区间,线段树优化建图+dijstra Codeforces Round #406 (Div. 2) D

    http://codeforces.com/contest/787/problem/D 题目大意:有n个点,三种有向边,这三种有向边一共加在一起有m个,然后起点是s,问,从s到所有点的最短路是多少? ...

  4. aidl.exe'' finished with non-zero exit value 1问题解决【转载】

    PS:Android Studio用AIDL时,碰到一个非常棘手的问题,但是百度之,压根非法解决,FQ出去,终于找到了一篇解决问题的文章,特地转载之. 之前使用aidl传递的都是基本的数据类型比如in ...

  5. placeholder样式设置

    在input框中有时想将输入的字和placeholder设为不同的颜色或其它效果,这时就可以用以下代码来对placeholder进行样式设置了. ::-webkit-input-placeholder ...

  6. CentOS7最小化安装连接到网络的解决方案

    周末在家想装个虚拟机学一下Hadoop啥的,因为网速小水管比较慢所以下载的是CentOS的minimal版本的: 这个版本安装完之后默认是没有安装net-tools的,也就是说ifconfig不能用: ...

  7. windows安装linux虚拟机、修改apt源

    记录一下windows安装虚拟机以及初始配置的一些坑. 安装VMware Workstation 直接百度搜索VMware,选择合适的版本下载: 按照一般软件的安装步骤安装VMware Worksta ...

  8. C/C++——#和##操作符

    1. #操作符 使用阶段:预处理阶段,只有宏定义中使用(#define) 作用:将宏参数转换为字符串 示例: #define STRING(x) #x 2. ##操作符 使用阶段:预处理阶段,只有宏定 ...

  9. redis aof文件过大问题

    http://www.itnose.net/detail/6682725.html 最近新安装了一台redis,版本为redis-3.2.5 数据盘用的是固态硬盘. 之前用的是普通硬盘,redis日志 ...

  10. Linux Supervisor的安装与使用入门---Ubuntun

    Linux Supervisor的安装与使用入门 在linux或者unix操作系统中,守护进程(Daemon)是一种运行在后台的特殊进程,它独立于控制终端并且周期性的执行某种任务或等待处理某些发生的事 ...