算法题解----字节跳动春招后端编程题
问题描述:
有三只球队,每只球队编号分别为球队1,球队2,球队3,这三只球队一共需要进行 n 场比赛。现在已经踢完了k场比赛,每场比赛不能打平,踢赢一场比赛得一分,输了不得分不减分。已知球队1和球队2的比分相差d1分,球队2和球队3的比分相差d2分,每场比赛可以任意选择两只队伍进行。求如果打完最后的 (n-k) 场比赛,有没有可能三只球队的分数打平。
输入描述:
第一行包含一个数字 t (1 <= t <= 10) 接下来的t行每行包括四个数字 n, k, d1, d2(1 <= n <= 10^12; 0 <= k <= n, 0 <= d1, d2 <= k)
输出描述:
每行的比分数据,最终三只球队若能够打平,则输出“yes”,否则输出“no”
输入样例:
2 3 3 0 0 3 3 3 3
输出样例:
yes
no
这道题不涉及什么高难度的算法,就是非常普通的逻辑推断。
这道题我么可以这样设:第一支队伍得分为 x + d1 , 第二支为 x 第三支为 x + d2。
由于已经比过了k场,且比赛输掉的队伍不会扣分,所以三支队伍得分总和应该为k
所以我们可以得到:
3 * x + d1 + d2 = k
我们就可以把每支队伍的得分求出来
然后找到得分最高的队伍,把其他队伍的分数都补到和得分最高的队伍的分数
如果剩余的场数不够补分或者减去补分的场数不能被3整除,那么就一定无法达到平局。
代码如下:
# include <iostream> using namespace std; typedef long long LL; bool check(LL n,LL k,LL d1, LL d2) { if((k-d1-d2) % 3 != 0) return false; LL t2 = (k-d1-d2)/3; LL t1 = t2+d1; LL t3 = t2+d2; if(t1<0 || t2<0 || t3<0) return false; LL max1 = max(t1,t2); max1 = max(max1,t3); LL a = 3*max1-t1-t2-t3; if(n-k-a<0) return false; if((n-k-a)%3==0)return true; else return false; } int main() { int t; cin>>t; while(t--) { LL n,k,d1,d2; cin>>n>>k>>d1>>d2; if(check(n,k,d1,d2)||check(n,k,-d1,d2)||check(n,k,d1,-d2)||check(n,k,-d1,-d2)) cout<<"yes"<<endl; else cout<<"no"<<endl; } return 0; }
这题还要注意题目给的数字范围很大,所以我开了long long