题目描述

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

示例1

输入

2
3 3 0 0
3 3 3 3

输出

yes
no

说明

case1: 球队1和球队2 差0分,球队2 和球队3也差0分,所以可能的赛得分是三只球队各得1分
case2: 球队1和球队2差3分,球队2和球队3差3分,所以可能的得分是 球队1得0分,球队2得3分, 球队3 得0分,比赛已经全部结束因此最终不能打平。

思路:这道题要是考虑所有情况的话贼复杂,还是需要列方程后分类讨论,通过题意我们可以很容易列出方程:

字节跳动历届笔试题(1)_#include

之后直接针对d1和d2的符号进行分类讨论即可。只有当a+b+c!=k或者a,b,c其中一个是负数或者大于n/3时才是非法的。

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define mod 1000000007
#define ll long long
ll n,k,d1,d2;
int main(void){
    int t;
    scanf("%d",&t);
    while(t--){
        bool flag=true;
        scanf("%lld%lld%lld%lld",&n,&k,&d1,&d2);
        if(n%3!=0)
            printf("no\n");
        else{
            int flag=0;
            for(int x=-1;x<=1 && !flag;x+=2)
                for(int y=-1;y<=1;y+=2){
                    ll dd1=d1*x;
                    ll dd2=d2*y;
                    ll a=(k-2*dd1+dd2)/3;
                    ll b=(k+dd1+dd2)/3;
                    ll c=(k+dd1-2*dd2)/3;
                    if(a+b+c!=k || a<0 || b<0 || c<0)
                        continue;
                    if(a>n/3 || b>n/3 || c>n/3)
                        continue;
                    flag=1;
                    break;
                }
            if(flag)
                printf("yes\n");
            else
                printf("no\n");
        }
    }
    return 0;
}