• CXB 移动“哨兵棋子”


    题解

            一条数轴有N个棋子,每个棋子可以占据一个整数位置。N个棋子目前位于不同的整数位置,现在你想要移动它们以便它们占据N个连续位置(例如,位置5,6,7)。当前所有棋子中位置最小或者位置最大的棋子,称为“哨兵棋子”。每一次,你只能移动“哨兵棋子”。你可以把“哨兵棋子移动到当前任何未占用的整数位置,前提是在这个新位置该棋子不再是“哨兵棋子。”请确定使得N个棋子最终占据连续的N个位置的最小移动次数和最大移动次数。

    输入格式

            第一行,一个整数N。3<=N<=100000。

            接下来有N行,第i行是一个整数,表示第i个棋子的位置,整数范围[1,1000000000]。

    输出格式

            第一行,一个整数,最小移动次数。

            第二行,一个整数,最大移动次数。

    输入样例

    3

    7

    4

    9

    输出样例

    1

    2

    题解

            先说最小次数。

            我们把最后的连续位置看作一个区间,那么最小移动次数实际上就是$n$减去这个区间原有的棋子数量,用尺取法求即可。

             但是这里要特判一种情况,就是整条数轴只分成两部分连续的棋子,且其中一部分只有一个棋子。容易得到,如果这两个部分之间间隔为$1$,那么最小移动次数就是$1$。否则,先把另一部分中的一个棋子移到那个部分的一边,再把只有一个棋子部分的棋子移进刚刚移出的空,最小移动次数为$2$。

            最大次数也很简单,实际上最大移动次数就是棋子一个一个“滚”到一起,如下所示:

    ___#_#___#___

    _____##__#___

    ______##_#___

    _______###___

            容易想到,最大移动次数就是第$1$个棋子到第$n$个棋子之间的空位数量减去刚开始移动一个哨兵棋子所减少的最小空格数量。

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    
    #define MAX_N (100000 + 5)
    
    using namespace std;
    
    int n;
    int a[MAX_N];
    int ans1, ans2;
    
    int main()
    {
         scanf("%d", &n);
         for(register int i = 1; i <= n; ++i)
         {
             scanf("%d", a + i);    
        }
        sort(a + 1, a + n + 1);
        ans1 = n;
        for(register int i = 1, j = 1; j <= n; ++j)
        {
            if(a[j] - a[i] < n) ans1 = min(ans1, n - (j - i + 1));
            else ++i;
        }
        if(a[n] - a[2] + 1 == n - 1 && a[2] - a[1] - 1 > 1)
        {
            ans1 = 2;
        }
        else if(a[n - 1] - a[1] + 1 == n - 1 && a[n] - a[n - 1] - 1 > 1)
        {
            ans1 = 2;
        }
        ans2 = a[n] - a[1] - (n - 1) - min(a[2] - a[1] - 1, a[n] - a[n - 1] - 1);
        printf("%d
    %d", ans1, ans2);
        return 0;
    }
    参考程序
  • 相关阅读:
    使用Flex Bison 和LLVM编写自己的编译器[zz]
    应用开发框架讨论应用配置wxFileConfig
    交流电220V是从何而来的
    电压、电流、电阻的概念
    电路返回端,接地,大地,等势体,静电场,回路,电能
    泛型实现List(List<T>)排序
    javascript注册功能
    层(div或table)的左右滚动
    javascript正则表达式检验
    JavaScript通用类库(ZT)
  • 原文地址:https://www.cnblogs.com/kcn999/p/10743076.html
Copyright © 2020-2023  润新知