首页 > 代码库 > CodeChef Consecutive Snakes 三分(整数)

CodeChef Consecutive Snakes 三分(整数)

 题意

在年度阅兵中,所有的士兵蛇都在阅兵场集合了,但这些蛇的站位不对。整场阅兵必须能从主席台看清楚,所有蛇都应该站成一排。但这些士兵非常懒惰,你必须指挥士兵重新排队,使得所有人的移动距离之和最短。

形式化地,整支阅兵队伍可以视作一条数轴。共有N条蛇,每条蛇是一根长度为L的线段。第i条蛇初始时占据了[Si,Si + L]的区间,蛇与蛇之间可以重合。能从主席台看到的只有区间[A,B],因此所有的蛇都应该处于这个区间内。蛇应该排列成连续一段,之间不能留缝隙,即这些蛇从前往后应该依次占据[X,X+L],[X +L,X+2L], ...,[X+(N−1)L,X+NL] 这些区间,其中A<=X<=X+NL<=B。保证 [A,B] 足以排下所有的蛇。

如果一条蛇初始时位于 [X1,X1+L],重排后位于 [X2,X2+L],那么这条蛇的移动距离为|X2−X1|。你需要将蛇重新排列,使得排列后满足上述条件,并最小化所有蛇的移动距离之和。

你需要输出最短距离和。

数据

输入的第一行包含一个整数T,代表测试数据的组数。接下来是T组数据。

每组数据第一行包含四个整数N、L、A和B,分别代表蛇的条数、蛇的长度,以及从主席台可见的区间[A,B]。

接下来一行包含N个整数S1, S2,..., SN,代表每条蛇初始所处区间的左端点。

对于每组数据,输出一行,包含一个整数,代表最短距离和。

1<=T<=10; 3<=N<=1e5; 1<= Si,L<=1e9; 1<=A<=B<=1e9; NL<=B-A

输入

2

3 4 11 23

10 11 30

3 4 11 40

10 11 30

输出

16

16

说明

 

第一组数据中,三条蛇初始时位于 [10,14]、[11,15]、[30,34] 三个区间。一种最优解是将第1条蛇移动到 [15,19],第 3 条蛇移动到 [19,23]。移动距离和为|15−10|+|11−11|+|19−30| = 5+0+11 = 15。

第二组数据相较于第一组,只是主席台能看到的区间更大了而已。而事实上,最优解不变。

 

题解:

  第一条蛇的左边端点可以三分,所以我们三分这个点,算一算花费就可以了。特别要注意的是三分的左右边界。

#include<bits/stdc++.h>using namespace std;#pragma comment(linker, "/STACK:102400000,102400000")#define ls i<<1#define rs ls | 1#define mid ((ll+rr)>>1)#define pii pair<int,int>#define MP make_pairtypedef long long LL;const long long INF = 1e18+1LL;const double Pi = acos(-1.0);const int N = 1e5+10, M = 1e3+20, mod = 2017,inf = 2e9;int a[N],n,L,A,B,T;LL cal(int x) {    LL sum = 0;    for(int i = 1; i <= n; ++i) {        sum += abs(x - a[i]);        x += L;    }    return sum;}int main() {    scanf("%d",&T);    while(T--) {        scanf("%d%d%d%d",&n,&L,&A,&B);        for(int i = 1;i <= n; ++i) scanf("%d",&a[i]);        sort(a+1,a+n+1);        int l = A, r = B - n*L;        while(l + 2 < r) {            int x = (r - l)/3 + l;            int y = (r - l)/3 * 2+l;            LL sum1 = cal(x);            LL sum2 = cal(y);            if(sum1 >= sum2) l = x;            else r = y;        }        LL ans = cal(l);        for(int i = l; i <= r; ++i)            ans = min(ans,cal(i));        cout<<ans<<endl;    }    return 0;}

 

CONSESNK: 连续的蛇题目描述在年度阅兵中,所有的士兵蛇都在阅兵场集合了,但这些蛇的站位不对。整场阅兵必须能从主席台看清楚,所有蛇都应该站成一排。但这些士兵非常懒惰,你必须指挥士兵重新排队,使得所有人的移动距离之和最短。形式化地,整支阅兵队伍可以视作一条数轴。共有 N 条蛇,每条蛇是一根长度为 L 的线段。第 i 条蛇初始时占据了 [Si, Si + L] 的区间,蛇与蛇之间可以重合。能从主席台看到的只有区间[A, B],因此所有的蛇都应该处于这个区间内。蛇应该排列成连续一段,之间不能留缝隙,即这些蛇从前往后应该一次占据 [X, X + L], [X + L, X + 2L], . . . , [X + (N − 1)L, X + NL] 这些区间,其中 A ≤ X ≤ X + NL ≤ B。保证 [A, B] 足以排下所有的蛇。如果一条蛇初始时位于 [X1, X1 + L],重排后位于 [X2, X2 + L],那么这条蛇的移动距离为|X2 − X1|。你需要将蛇重新排列,使得排列后满足上述条件,并最小化所有蛇的移动距离之和。你需要输出最短距离和。输入格式输入的第一行包含一个整数 T,代表测试数据的组数。接下来是 T 组数据。每组数据第一行包含四个整数 N、L、A 和 B,分别代表蛇的条数、蛇的长度,以及从主席台可见的区间 [A, B]。接下来一行包含 N 个整数 S1, S2, . . . , SN,代表每条蛇初始所处区间的左端点。输出格式对于每组数据,输出一行,包含一个整数,代表最短距离和。数据范围与• 1 ≤ T ≤ 10• 3 ≤ N ≤ 105• 1 ≤ Si, L ≤ 109• 1 ≤ A ≤ B ≤ 109• NL ≤ B − A样例数据输入23 4 11 2310 11 303 4 11 4010 11 30输出16161SnackDown Pre-elimination Round A 2017样例解释第一组数据中,三条蛇初始时位于 [10, 14]、[11, 15]、[30, 34] 三个区间。一种最优解是将第 1 条蛇移动到 [15, 19],第 3 条蛇移动到 [19, 23]。移动距离和为 |15−10|+|11−11|+|19−30| = 5+0+11 = 15。第二组数据相较于第一组,只是主席台能看到的区间更大了而已。而事实上,最优解不变。

CodeChef Consecutive Snakes 三分(整数)