题解 P1326 【足球】
首先,我是一个球迷,常年观看中超联赛,所以看到这道题就格外亲切。
求最大得分的思路:
在比赛 n 场的前提下,肯定是赢得越多越好,想要赢得多,核心思想就是节省进球数,浪费丢球数,分为下面两种情况:
(1)进球数小于比赛场数,即 s < n.
既然要节省进球数,浪费丢球数,那么就索性赢 s 场 1:0,把所有丢球都丢在同一场,也就是输一场 0: t 。这时最多赢 s 场,最少输一场,所以平局数就是 n - s - 1 场,积分就是 3s + n - s - 1。但是有一种特殊情况,就是当 t == 0 时,输的那场 0 : t 其实是平局,所以当 t == 0 时,积分要 + 1 。
(2)进球数大于等于比赛场数,即 s >= n.
此时我们还是要浪费丢球数,把所有丢球都丢在同一场,因为 s >= n ,所以赢 n - 1 场 1 :0 是没问题的,积分就是 3(n - 1)。赢完之后我们还剩下 s - (n - 1) 个进球,最后一场我们将剩下的进球数与丢球数比较,如果进球数大于丢球数,那么最后一场就能赢,积分 + 3;如果进球数等于丢球数,那么最后一场就是平局,积分 + 1;如果进球数小于丢球数,那么最后一场就会输,积分不变。
求最小得分的思路:
求最小得分时,不能简单地说输得越多越好,因为赢一场输一场是 3 分,平两场却是 2 分,所以求最小得分时,要比较赢一场,剩下所有场次都不赢,和所有场次都不赢的最小值,也分为下面两种情况。
(1)进球数大于丢球数,即 s > t.
遇上这种情况,想一场不赢是不可能的,哪怕全是平局,也还有剩余的进球数。所以我们只能让他赢一场 s : 0 ,通过这场球把所有进球数都消耗掉, 积分变为 3 分。剩下的 n - 1 场再输 t 场 0 :1, 如果 t >= n - 1,那么我们就可以做到剩下的 n - 1 场全输,积分就是 3 分;如果 t < n - 1,那么剩下的 n - 1 - t 场就只能是平局,这时积分就是 3 + n - 1 - t.
(2)进球数小于等于丢球数,即 s <= t.
这时我们终于有了所有场次都不赢的可能。因为要节省丢球数,所以每场比赛的丢球数都只比进球数多 1 个,输球场次就是 (s - t) 场,如果 (s - t) >= n,那么所有场次全输,积分就是 0,如果 (s - t) < n,那么剩下的 n - (s - t) 场就是平局,积分就是 n - (s - t).
另一种可能就是上一种情况里说的,赢一场,剩下的场次一场不赢,最后在这两种情况里取最小值就可以了。
#include<cstdio>
#include<iostream>
using namespace std;
int main()
{
long long mx, mn, s, t, n;
while(~scanf("%lld %lld %lld", &s, &t, &n))
{
mx = mn = 0;
if(s < n)
{
mx += s * 3;
mx += n - s - 1;
if(!t)
mx++;
printf("%lld ", mx);
}
else
{
mx += (n - 1) * 3;
if(s - (n - 1) > t)
mx += 3;
else if(s - (n - 1) == t)
mx++;
printf("%lld ", mx);
}
if(s > t)
{
mn += 3;
if(t < n - 1)
mn += n - 1 - t;
printf("%lld ", mn);
}
else
{
long long a = 3, b = 0;
if(t < n - 1)
a += n - 1 - t;
if(n > t - s)
b = n - (t - s);
printf("%lld ", min(a, b));
}
printf("\n");
}
return 0;
}