您的位置:首页 > 其它

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

2015-09-10 13:06 316 查看
题目链接

这个题已经过了一年了。。。本来当时就想写题解但是没找到题。。最近有人问我才知道原来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;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: