• 【t072】国际象棋


    Time Limit: 1 second
    Memory Limit: 128 MB

    【问题描述】

    有N个人要参加国际象棋比赛,该比赛要进行K场对弈。每个人最多参加2场对弈,最少参加0场对弈。每个人都有一个与其他人都不
    相同的等级(用一个正整数来表示)。在对弈中,等级高的人必须用黑色的棋子,等级低的人必须用白色的棋子。每一个人最多
    只能用一次黑色的棋子和一次白色的棋子。为了增加比赛的可观度,观众希望K场对弈中双方的等级差的总和最小。
    比如有7个选手,他们的等级分别是30; 17; 26; 41; 19; 38; 18,要进行3场比赛。最好的安排是Player 2 vs Player 7,
    Player7 vs Player 5 , Player 6 vs Player 4,此时等级差的总和等于(18-17) + (19-18) + (41-38) = 5达到最小。
    在90%的数据中,1≤N≤3000
    在100%的数据中,1≤N≤100000
    保证所以输入数据中等级的值小于108,1≤K≤N-1

    【输入格式】

     第一行两个正整数N,K。
    接下来有N行,第i行表示第i-1个人等级。

    【输出格式】

    在第一行输出最小的等级差的总和。

    Sample Input

    7 3
    30
    17
    26
    41
    19
    38
    18

    Sample Output

    5

    【题目链接】:http://noi.qz5z.com/viewtask.asp?id=t072

    【题解】

    先把所有人的等级从小到大排个序;
    排序之后;等级相近的两个人就会靠在一起;
    而两个相近的人,它们的等级差是最小的;
    这样对于
    i-1,i,i+1;
    可以让a[i-1]和a[i],a[i]和a[i+1]两对人来对弈;
    a[i-1]< a[i]< a[i+1]
    这样a[i]会对弈两次,且两次,它一次用黑棋一次用白棋,没有违反规则,然后a[i]最多对弈两次;
    然后把a[i]-a[i-1]作为新的b[i],然后对b[i]再升序排,取前k个b就好;累加一下;
    b[k] = a[k+1]-a[k];
    取b[k]就相当于k+1和k对弈;
    (相邻是最近的,这个就是贪心点吧.)

    【完整代码】

    #include <algorithm>
    #include <cstdio>
    
    using namespace std;
    
    const int MAXN = 1e5+100;
    
    int n,k;
    int a[MAXN];
    long long ans;
    
    int main()
    {
        //freopen("F:\rush.txt","r",stdin);
        scanf("%d%d",&n,&k);
        for (int i = 1;i <= n;i++)
            scanf("%d",&a[i]);
        sort(a+1,a+1+n);
        for (int i = 2;i <= n;i++)
            a[i-1] = a[i]-a[i-1];
        sort(a+1,a+1+n-1);
        for (int i = 1;i <= k;i++)
            ans+=a[i];
        printf("%I64d
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    Godaddy注册的域名转发、转向教程
    Flash的attachMovie方法
    js出现中文乱码及VS打开js文件乱码的解决方法
    sql2005 COM+ 目录要求 (警告)
    flash读取不同格式xml
    Flash xml 中文乱码
    IXWebHosting的URL转向设置
    引用项目类库时dll.refresh文件的影响
    flash自定义函数
    Microsoft SQL Server 2005 整合、集成SP3方法
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7626676.html
Copyright © 2020-2023  润新知