题意描述:
我们当中有很多热爱中国足球的同学,我们都知道中超(中国足球超级联赛)的规则:
一场比赛中,若获胜(即你的得分严格大于对手得分)则获得3的积分。
若打平(即你的得分等于对手得分)则获得1分。
若失败(即你的得分严格小于对手得分)获得0积分。
这个问题很简单,假设轮中比赛中你一共攻入个球,丢掉个球,那么你可能获得的最大得分和最小得分是多少?
输入格式:
多组数据,每组数据一行:
一行三个整数、、
输出格式:
对于每组数据输出一行,两个整数表示最大得分和最小得分。
Input & Output 's examples
Input 's eg
1 1 1 1 1 2
Output 's eg
1 1 3 2
数据范围和约定
保证所有数据均在long long(即int64)范围之内
分析
一道贪心好题,但绝对没有紫题的难度。
首先,题目要求我们求最大值与最小值。因此,我们需要对两个答案分类讨论。
MAX
既然要求得分最大,那么我们要让赢的场数尽量的多。
那么我们的核心思想在于尽量让更多的场进球,更少的场输球
分以下两种情况讨论:
进球数 > 场数
如果进球数大于比赛场数的话,理论上我们就一定以1 : 0
可以赢场。
但是我们还要处理丢掉的球。
因此,我们只需要先以1 : 0
赢场,得分为.
对于剩下的一场,我们还需要进行分类讨论。
我们提前算出我们还要进球的数量,即,如果大于我们输的球就加3分,等于加1分,小于不加分。
进球数 <= 场数
在这种情况下,我们最多只能以1 : 0
赢场,得分为。
对于剩下的场数,我们需要尽量达成平局。因此我们只需要输一场来处理丢掉的球,得分为。
但要注意,如果此时的,即没有丢球的话,我们就不需要输了,则此时的得分为
MIN
求最小值时,我们不能简单地说输的越多越好,因为赢一场就是3分,而平三场才有三分。
因此我们求最小值时需要比较赢一场,剩下都输与有的平局有的输两种情况。
下面我们还是分两种情况进行分类讨论。
进球数 > 丢球数
此时,我们一定不可能一场都不赢,因为就算全是平局,也会有剩下的进球数。
因此我们就让他以S : 0
先赢一次,浪费掉所有的进球数。
对于剩下的场,如果,即剩下的场数大于输球数,我们就让他输掉场,剩下的都为平局。此时得分为
如果,即剩下的场数小于等于输球数,那么我们就让他全部输掉。此时得分为3分。
进球数 <= 丢球数
啊,终于可以一场都不赢了
因为我们要尽量多输几场,所以每场比赛比分都是0 : 1
。因此我们要看与的大小关系。
如果 大于等于,那么每一场都输掉。得分就是0分、
否则用平局补充,得分就是。
还有就是不要忘了赢一局可能比用平局更低的情况……
最后的答案在这两种里取最小值就好了。
Code[Accepted]
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<stack> #include<queue> #include<deque> #include<vector> #include<iomanip> #include<cstdlib> #include<cctype> #include<cmath> #define ll long long #define I inline using namespace std; ll s , t , n; I ll MAX(ll s , ll t , ll n){ ll ans = 0; if(s >= n){ ans += 3 * (n - 1); if(s - n + 1 > t){ ans += 3; } else if(s - n + 1 == t){ ans += 1; } return ans; } if(s < n){ if(t == 0){ return 3 * s + (n - s); } return 3 * s + (n - s - 1); } } I ll MIN(ll s , ll t , ll n){ ll ans = 0; if(s > t){ ans += 3; if(n - 1 > t){ ans += n - 1 - t; } return ans; } else if(s <= t){ ll a = 3, b = 0; if(t < n - 1){ a += n - 1 - t; } if(n > t - s){ b = n - (t - s); } return min(a , b); } } int main(){ while(cin >> s >> t >> n){ cout << MAX(s , t , n) << " " << MIN(s , t , n) << "\n"; } return 0; }