UVa Live 7147 贪心(2014 上海区域赛)

题目链接

这个题已经过了一年了。。。本来当时就想写题解但是没找到题。。最近有人问我才知道原来UVa Live有历年题目。。。

去年在现场的时候这题也是卡了好久。。。重写了两三次。。封榜了才过。。

题意:有n只队伍,每只队伍要和其他n-1只队伍比赛,每场比赛获胜得a分,平局得b分,败北得c分,共有m只队伍可以晋级,问最高淘汰分和最低晋级分分别是多少。

思路:这个题的细节真的很多。。

首先如果获胜分<败北分,互换两个分数。

然后考虑分数尽量平均的分配方式:

在偶数个人中,想让所有人分数相等有两种方式,所有人平局或赢一半的人输一半的人;

在奇数个人中,要么所有人平局,要么一部分人多输一局。

最高淘汰分:第m+1人,对于其后面的n-m-1人都应该选择赢或者平局,对于前面的m人,按照上面的分数分配方式选择分较高的一种。

最低晋级分:第m人,对于其前面的m-1人都应该选择输或平局,对于后面的n-m人,按照上面的分数分配方式选择分较少的一种。

这道题的细节很多,有一个需要注意的地方是对于奇数个人m,不应该比较m/2 * (win + lose)和 m * draw,这样draw会多算一个,我就在这个地方卡了很久。。。(好像当时比赛的时候也在这里卡了很久。。)

#include <iostream>
#include <algorithm>
using namespace std;

main() {
    long long n, m, win, draw, lose;
    int t, cas = 1;
    cin >> t;
    while(t--){
        cin >> n >> m >> win >> draw >> lose;
        if(win < lose) swap(win, lose);
        long long pass = 0, out = 0;
        if(m % 2 == 0){
            if(draw < lose) pass = draw * (n - 1);//如果平局分数最低 那么最低晋级分就是所有人平局
            else {
                pass = (m - 1) * lose;//和前面的m-1人比一定是输的
                long long p = n - m;
                pass += (p / 2) > 0 ? min(win + lose, draw + draw) * (p / 2) : 0;//和后面的人比,看哪种分数相同的情况分数最低
                if(p % 2) pass += min(draw, win);//如果是奇数情况,那么要么赢最后一名,要么所有人平局,反正总分要低
            }
            if(draw > win) out = draw * (n - 1);//如果平局分数最低 那么最高淘汰分就是所有人平局
            else{
                out = (m / 2) > 0? max(win + lose, draw + draw) * (m / 2) : 0;//和前面的人比,看哪种分数分数相同的情况分数最高
                out += (n - m - 1) * win;//和后面的人比一定是赢的
            }
        }
        else {
            if(draw < lose) pass = draw * (n - 1);
            else{
                pass = (m - 1) * lose;
                long long p = n - m;
                pass += (p / 2) > 0 ? min(win + lose, draw + draw) * (p / 2) : 0;
                if(p % 2) pass += min(win, draw);
            }
            if(draw > win) out = draw * (n - 1);
            else {
                out = (m / 2) > 0? max(win + lose, draw + draw) * (m / 2) : 0;
                out += max(draw, lose) + (n - m - 1) * win;//和前面的人比 如果是奇数情况 要么平要么输 选分高的一种
            }
        }
        cout << "Case #" << cas++ << ": " << out << " " << pass << endl;
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值