UVALive 7147
题意
对于单循环赛(每个队都要跟其他的每一个队打且只打一场比赛)
赢积A分,输积C分,平都积B分,ABC均非负但不保证A>B>C
共有n个队,其中m个能晋级,分数相同的用抽签来决定谁晋级
求最多拿多少分仍有可能晋级失败,最少拿多少分仍有晋级可能
当时我们队的思路是
先按照A>B>C的符合常识的情况来推公式
那么
想法很单纯
对于第一个答案,【要尽量让那个包含被毫无悬念地淘汰的队伍的集合,得到最少的分数,这样可以让前面晋级的队伍的分数冲高】
对于第二个答案,【要尽量让那个包含毫无悬念地晋级的队伍的结合,得到尽可能多的分数,这样可以让包含踩在晋级临界线的队伍和毫无悬念被淘汰的队伍的集合包含尽可能少的分数】
这样不难推出一个公式
然后用类似的想法 可以推出以下各种情况
A>B>C且2B < A+C
A>B>C且2B > A+C
B>max(A, C)
B<min(A, C)
其中A、C的大小关系无所谓,若A<C,swap一下即可
可以分成四种情况推公式
不过我们队是把各种情况都统一成一份公式 具体见代码
#include <iostream> #include <cstdlib> #include <cstdio> #include <algorithm> #include <iostream> #include <cstring> #include <cmath> using namespace std; typedef long long ll; const int maxn = 15; int main() { //freopen("in.txt", "r", stdin); int T; scanf("%d", &T); int kase = 0; while(T--) { printf("Case #%d: ", ++kase); ll n, m; ll a, b, c; scanf("%lld%lld", &n, &m); scanf("%lld%lld%lld", &a, &b, &c); if(a < c) swap(a, c); ll ans1, ans2; if(a + c < 2 * b) { ans1 = (n - m - 1) * max(a, b) + m * b; ans2 = (m-1)*min(b,c) + (n-m)/2*(a+c) + (n-m)%2*min(a,b); } else { ans1 = (n - m - 1) * max(a, b) + m/2*(a+c) + m%2*max(b,c); ans2 = (m-1)*min(b,c) + (n-m)*b; } printf("%lld %lld ", ans1, ans2); } return 0; }