算法题解----字节跳动春招后端编程题

问题描述:

有三只球队,每只球队编号分别为球队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

 

posted @ 2021-08-23 16:19  Apak陈柏宇  阅读(197)  评论(0编辑  收藏  举报