首页 > 代码库 > 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 三分(整数)