• UVALive 7147 World Cup


    https://icpcarchive.ecs.baylor.edu/index.phpoption=com_onlinejudge&Itemid=8&page=show_problem&problem=5159

    题目大意:n个队伍参加比赛,有m个队伍晋级,n个队伍有n-1场比赛,每两个队伍之间都有一场比赛。一场比赛赢的得a分,输的得c分,平局得b分,问没有晋级的队伍最高分和晋级的队伍最低分

    分析:

    1.没有晋级的队伍最高分

    将队伍分为两堆,分别为m+1,n-m-1;令第m+1个队伍就是没晋级分数最高的队伍

    第m+1个人与第二堆里面的队伍的n-m-1场比赛中得分要么每场都赢,要么每场都平局

    即第m+1个人的得分: (n-m-1)*max(a, b);

    贪心的让第一堆的分数高,要使第m+1个队伍就是没晋级分数最高的队伍,有两种可能

    (1)第一堆m场比赛中所有队伍中每个队伍赢得场数和输的场数基本相同

    即第m+1个人得分 : m/2*a+m/2*c,即m/2*(a+c);

    (2)第一堆m场比赛中所有队伍都平局

    即第m+1个人得分:  m/2*b+m/2*b,即m/2*(b+b);

    与第一堆的比赛得分取以上两场比赛的最大值

    即:max(m/2*(a+c),m/2*(b+b));

    第一堆的m场比赛有可能是奇数场也有可能是偶数场,如果是奇数场那么第m+1个人的得分还得加上最后一场的得分,第一堆的最后一场比赛有可能输也有可能平局(不能赢,如果赢了那这个队就有可能比前m-1个队伍分高,就应该晋级),所以得分为max(b, c);

    最终第m+1个人的得分为:

    x = (n-m-1)*max(a, b)+max(m/2*a+m/2*c,m/2*b+m/2*b)

    如果m为奇数x+= max(b, c);否则为x;

    2.晋级的队伍最低分

    将队伍分为两堆,分别为m-1,n-m+1;令第m个队伍就是晋级分数最低的队伍

    第m个人与第一堆里面的队伍的m-1场比赛中得分要么每场都输,要么每场都平局

    即第m个人的得分: (m-1)*min(c, b);

    贪心的让第二堆的分数低,要使第m个队伍就是晋级分数最低的队伍,有两种可能

    (1)第二堆n-m场比赛中所有队伍中每个队伍赢得场数和输的场数基本相同

    即第m个人得分 : (n-m)/2*a+(n-m)/2*c,即(n-m)/2*(a+c);

    (2)第一堆n-m场比赛中所有队伍都平局

    即第m个人得分:  (n-m)/2*b+(n-m)/2*b,即(n-m)/2*(b+b);

    与第一堆的比赛得分取以上两场比赛的最小值

    即:min((n-m)/2*(a+c),(n-m)/2*(b+b));

    第二堆的n-m场比赛有可能是奇数场也有可能是偶数场,如果是奇数场那么第m个人的得分还得加上最后一场的得分,第一堆的最后一场比赛有可能赢也有可能平局(不能输,如果输的话,那该队得的分数就比第二堆其他队的分数低就不能晋级了),所以得分为min(b, a);

    最终第m个人的得分为:

    x = (m-1)*min(c, b)+min((n-m)/2*(a+c),(n-m)/2*(b+b))

    如果n-m为奇数x+= min(b, a);否则为x;

    #include<stdio.h>
    #include<string.h>
    #include<math.h>
    #include<algorithm>
    
    using namespace std;
    
    typedef long long ll;
    
    int main()
    {
        int t;
        ll n, m, a, b, c, x, y;
        int p = 0;
        scanf("%d", &t);
        while(t--)
        {
            p++;
            x = y = 0;
            scanf("%lld%lld", &n, &m);
            scanf("%lld%lld%lld", &a, &b, &c);
           if(a < c)
            swap(a, c);
           x += (n - m - 1) * max(a, b);
           x += max(m / 2*(a + c), m/2*(b + b));
           if(m % 2 != 0)
            x += max(b, c);
           y += (m - 1) * min(b, c);
           y += min((n - m) / 2 * (a + c), (n - m) / 2 *(b + b));
           if((n - m) % 2 != 0)
            y += min(a, b);
            printf("Case #%d: %lld %lld
    ", p, x, y);
        }
        return 0;
    }
  • 相关阅读:
    B1028人口普查
    B1004成绩排名
    B1041考试座位号
    A1009 Product of Polynomials多项式相乘
    A1002 A+B for Polynomials 多项式相加
    B1010一元多项式求导
    A1065 A+Band C(64 bit)
    A1046 Shortest Distance 最短路径
    排序
    windows 平台使用wireshark命令行抓包
  • 原文地址:https://www.cnblogs.com/qq2424260747/p/4905426.html
Copyright © 2020-2023  润新知