zoukankan      html  css  js  c++  java
  • 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_pair
    typedef 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 样例数据 输入 2 3 4 11 23 10 11 30 3 4 11 40 10 11 30 输出 16 16 1 SnackDown 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。 第二组数据相较于第一组,只是主席台能看到的区间更大了而已。而事实上,最优解不变。

  • 相关阅读:
    快逸报表调用存储过程(SqlServer)
    一个睡五分钟等于六个钟头的方法 (转)
    Windows Live Writer For Windows Server 2003
    设计模式装饰者模式
    SqlServerCUBE
    Android 70道面试题汇总不再愁面试
    说服力:让你的PPT会说话
    亮剑Java项目开发案例导航
    初入社会必知的88个潜规则
    android UI进阶之仿iphone的tab效果2
  • 原文地址:https://www.cnblogs.com/zxhl/p/7040849.html
Copyright © 2011-2022 走看看