首页 > 试题广场 >

编程题1

[编程题]编程题1
  • 热度指数:25911 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 64M,其他语言128M
  • 算法知识视频讲解
有三只球队,每只球队编号分别为球队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分,比赛已经全部结束因此最终不能打平。
import java.util.Scanner;

public class solution {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int t = Integer.parseInt(sc.nextLine());
        for (int i = 0; i < t; i++) {
            String s = sc.nextLine();
            String[] ss = s.split(" ");
            long n = Long.parseLong(ss[0]);
            long k = Long.parseLong(ss[1]);
            long d1 = Long.parseLong(ss[2]);
            long d2 = Long.parseLong(ss[3]);
            boolean target = game(n, k, d1, d2) || game(n, k, -d1, d2) || game(n, k, d1, -d2) || game(n, k, -d1, -d2);

            System.out.println(target ? "yes" : "no");
        }
    }

    public static boolean game(long n, long k, long d1, long d2) {
        long temp1 = 2 * d1 + d2;
        long temp2 = n - k;
        if (k >= temp1 && (k - temp1) % 3 == 0) {
            if ((temp1 + temp2) >= 0 && (temp1 + temp2) % 3 == 0 &&
                    (k - temp1) / 3 <= n / 3 &&
                    (k - temp1) / 3 + d1 <= n / 3 &&
                    (k - temp1) / 3 + d1 + d2 <= n / 3
            ) return true;
            else return false;
        } else {
            return false;
        }
    }
}
发表于 2019-04-11 10:54:30 回复(0)
其实不需要分类讨论……真正的分类讨论比这个难多了,我提供一个简单的代码吧
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
    ios::sync_with_stdio(false);
    int t;
    cin>>t;
    while(t--){
        ll n,k,d1,d2;// as 
        cin>>n>>k>>d1>>d2;
        bool sud=0;
        vector<int>possible={-1,1};
        for(auto kind_d1:possible){
            for(auto kind_d2:possible){
                ll s1=0,s2,s3;//sorce for every team
                s2=s1+kind_d1*d1;
                s3=s2+kind_d2*d2;
                ll tmp=0;
                if(min({s1,s2,s3})<0)tmp-=min({s1,s2,s3});
                s1+=tmp,s2+=tmp,s3+=tmp;
                ll dif=3*max({s1,s2,s3})-(s1+s2+s3);
                if(dif<=n-k && n%3==0 && (s1+s2+s3)<=k && (s1+s2+s3-k)%3==0)sud=1;
            }
        }
        cout<<(sud?"yes":"no")<<endl;
    }
}

发表于 2021-03-13 16:45:40 回复(0)
#include<bits/stdc++.h>
using namespace std;

int main(){
    int t;
    cin>>t;
    while(t--){
        long int n, k, d1, d2;
        cin>>n>>k>>d1>>d2;
        if(n % 3 != 0) {cout<<"no"<<endl; continue;}
        int S[] = {-1,1};
        bool flag = 0;
        for(auto s1:S){             //遍历d1,d2的正负
            for(auto s2:S){
                long int x1 = k -2*s1*d1 - s2*d2;
                if(x1%3 != 0) continue;
                else{
                    x1 /= 3;
                    long int x2 = x1 + s1*d1;
                    long int x3 = x2 + s2*d2;
                    auto mi = min(min(x1,x2),x3);
                    auto ma = max(max(x1,x2),x3);
                    if(mi < 0) break;
                    if(ma <= n/3) flag = 1;
                }
            }
        }
        if(flag) cout<<"yes"<<endl;
        else cout<<"no"<<endl;
    }
    return 0;
}

发表于 2020-08-20 03:01:16 回复(0)


常规思路, 先解方程组
得到图片说明
计算出图片说明 的四种情况,判断合法后计算出a,b,c的得分
三者都拿到最高分需要图片说明 场。
必然有
同时多出来的场次 必须每方各赢一场,也就是是3的倍数才满足题意。


#include<iostream>
using namespace std;
int flag[4][2] = {{1,1},{-1,-1},{1,-1},{-1,1}}; // 两个差值的四种符号情况
int main(){
    int t, f = 1;
    long long n, k, d1, d2;
    cin >> t;
    while(t--){
        // 得到解置f为0
        f = 1;
        cin >> n >> k >> d1 >> d2;
        for(int i = 0;i < 4 && f == 1;i++){
            long long  tempd1 = flag[i][0] * d1;
            long long  tempd2 = flag[i][1] * d2;
            long long  tempa = 2 * tempd1 + tempd2 + k;
            if(tempa < 0 || tempa % 3 != 0)
                continue;
            else{
                long long a = tempa / 3;
                long long b = a - tempd1;
                long long c = k - a - b;
                if(b < 0 || c < 0)
                    continue;
                else{
                    long long maxscore = (a > b ? max(a, c) : max(b, c));
                    long long re***axscore * 3 - a - b - c;
                    if(res == n - k || (res < n-k && (n - k - res) % 3 == 0))
                        f = 0
                    }
        }
        if(f == 1)
            cout<<"no"<<endl;
        else
            cout<<"yes"<<endl;
    }
    return 0;
}
编辑于 2019-05-21 21:20:19 回复(0)
class Solution
{
public:
    bool couldTie(int64_t n, int64_t k, int64_t d1, int64_t d2) {
        // 用s1, s2, s3分别表示三个队的头条分数
        int64_t remain = n - k;
        // 第一个santisfy表示满足case1: s1 > s2 > s3的条件
        // 此时s1 至少为d1+d2, s2至少为d2, s3至少0,k余下的场次数需是3的倍数
        // 第二个santisfy为余下的场次能打成平局的条件
        // s2再赢d1场,s3再赢d1+d2场, n - k余下的场次数需是3的倍数
        if (Satisfy(k, d1 + 2 * d2) && Satisfy(remain, 2 * d1 + d2)) {
          return true;
        }
        // case2: s1 < s2 < s3
        if (Satisfy(k, 2 * d1 + d2) && Satisfy(remain, d1 + 2 * d2)) {
          return true;
        }
        // case3: s2最小
        if (Satisfy(k, d1 + d2) && Satisfy(remain, 2 * max(d1, d2) - min(d1, d2))) {
          return true;
        }
        // case4: s2最大
        if (Satisfy(k, 2 * max(d1, d2) - min(d1, d2)) && Satisfy(remain, d1 + d2)) {
          return true;
        }
        return false;
    }

    bool Satisfy(int64_t remain, int64_t demand) {
        return (remain >= demand && ((remain - demand) % 3 == 0)); 
    }
};

int main()
{
    Solution demo;
    int t;
    int64_t n, k, d1, d2;
    scanf("%d", &t);
    for (int i = 0; i < t; i++) {
        scanf("%lld%lld%lld%lld", &n, &k, &d1, &d2);
        printf(demo.couldTie(n, k, d1, d2) ? "yes\n" : "no\n");
    }
    return 0;
}
发表于 2019-04-10 15:36:48 回复(0)
先判断出三个队的分数,再回过来看这三个分数的最大值似否比n/3小
def k_2d1_d2(x,y,k,d1,d2):
    s1=(k-x*2*d1-y*d2)/3
    s2=s1+x*d1
    s3=s2+y*d2

    if s1%1==0 and s2%1==0 and s3%1==0 and 0<=s1<=k and 0<=s2<=k and 0<=s3<=k:
        # print(x, y, s1, s2, s3)
        return s1,s2,s3
    return -1,-1,-1

def fn(x,length):
    for i in range(0,length):
        n,k,d1,d2 = x[4*i],x[4*i+1],x[4*i+2],x[4*i+3]
        if n%3!=0:
            print("no")
            continue
        if k_2d1_d2(1,1,k,d1,d2)[0]>=0:
           s1, s2, s3 = k_2d1_d2(1, 1, k, d1, d2)
           # print(1,1)
           if  max(s1,s2,s3)<=n/3:
               print("yes")
               continue
        if k_2d1_d2(1,-1,k,d1,d2)[0]>=0:
           s1, s2, s3 = k_2d1_d2(1, -1, k, d1, d2)
           # print(1, -1)
           if max(s1,s2,s3)<=n/3:
               print("yes")
               continue
        if k_2d1_d2(-1,1,k,d1,d2)[0]>=0:
           s1, s2, s3 = k_2d1_d2(-1, 1, k, d1, d2)
           # print(-1, 1)
           if d1>d2:
               if  max(s1,s2,s3)<=n/3:
                   print("yes")
                   continue
           if d2>=d1:
               if  max(s1,s2,s3)<=n/3:
                   print("yes")
                   continue
        if k_2d1_d2(-1,-1,k,d1,d2)[0]>=0:
           s1, s2, s3 = k_2d1_d2(-1, -1, k, d1, d2)
           # print(-1, -1)
           if max(s1,s2,s3)<=n/3:
               print("yes")
               continue
        print("no")



if __name__ == "__main__":
    i = input()
    i = int(i)
    x= []
    for k in range(i):
        score = input().split(" ")
        for item in score:
            x.append(int(item))
    fn(x,i)
发表于 2019-03-11 11:47:39 回复(0)
t = int(input())
res = []
for i in range(t):
    n, k, d1, d2 =[int(x) for x in input().split()]
    if n % 3 != 0:
        res.append('no')
        continue
    ## 求出三个球队的得分
    if (k+2*d1+d2)%3 == 0 and (k-d1+d2)%3 == 0:
        x = (k+2*d1+d2) /3 
        y = (k-d1+d2) / 3
        z = k - x - y
        if (x >= 0 and y >= 0 and z >= 0):
            score1 = x
            score2 = y
            score3 = z
            max_score = max(score1, score2, score3)
            dif1 = max_score - score1
            dif2 = max_score - score2
            dif3 = max_score - score3
            if dif1 + dif2 + dif3 <= n - k :
                res.append('yes')
                continue
                
    if (k-2*d1+d2)%3 == 0 and (k+d1+d2)%3 == 0:
        x = (k-2*d1+d2) /3 
        y = (k+d1+d2) / 3
        z = k - x - y
        if (x >= 0 and y >= 0 and z >= 0):
            score1 = x
            score2 = y
            score3 = z
            max_score = max(score1, score2, score3)
            dif1 = max_score - score1
            dif2 = max_score - score2
            dif3 = max_score - score3
            if dif1 + dif2 + dif3 <= n - k :
                res.append('yes')
                continue
    if (k+2*d1-d2)%3 == 0 and (k-d1-d2)%3 == 0:
        x = (k+2*d1-d2) /3 
        y = (k-d1-d2) / 3
        z = k - x - y
        if (x >= 0 and y >= 0 and z >= 0):
            score1 = x
            score2 = y
            score3 = z
            max_score = max(score1, score2, score3)
            dif1 = max_score - score1
            dif2 = max_score - score2
            dif3 = max_score - score3
            if dif1 + dif2 + dif3 <= n - k :
                res.append('yes')
                continue
                
    if (k-2*d1-d2)%3 == 0 and (k+d1-d2)%3 == 0:
        x = (k-2*d1-d2) /3 
        y = (k+d1-d2) / 3
        z = k - x - y
        if (x >= 0 and y >= 0 and z >= 0):
            score1 = x
            score2 = y
            score3 = z
            max_score = max(score1, score2, score3)
            dif1 = max_score - score1
            dif2 = max_score - score2
            dif3 = max_score - score3
            if dif1 + dif2 + dif3 <= n - k :
                res.append('yes')
                continue
    
    res.append('no')

for i in range(len(res)):
    print(res[i])

发表于 2019-02-17 18:04:01 回复(0)
#include<stdio.h>
#include<iostream>
 
using namespace std;
 
typedef long long LL;
 
void GetABC(int i, LL a, LL *pb, LL *pc, LL d1, LL d2)
{
    switch (i)
    {
    case 0:
        *pb = a + d1;
        *pc = *pb + d2;
        break;
    case 1:
        *pb = a + d1;
        *pc = *pb - d2;
        break;
    case 2:
        *pb = a - d1;
        *pc = *pb + d2;
        break;
    case 3:
        *pb = a - d1;
        *pc = *pb - d2;
        break;
    }
}
 
int main()
{
    int T;
    for (cin >> T; T--; )
    {
        LL n, k, d1, d2;
        scanf("%lld%lld%lld%lld", &n, &k, &d1, &d2);
        //x的四种可能解的3倍,就是第一场可能出现的解
        //第一场的分数的3倍
        LL x[] = {k - 2 * d1 - d2,k - 2 * d1 + d2,k + 2 * d1 - d2,k + 2 * d1 + d2};
        bool flag = false;
        for (int i = 0; i < 4; i++)
        {
            int sum = 0;
            //判断第一场的分数是否为3的倍数
            for (LL t = x[i]; t; sum += t % 10, t /= 10) {}
            //第一场分数要合法才美剧判断
            if (sum % 3 == 0 && 0 <= x[i] / 3 && x[i] / 3 <= k)
            {
                LL a = x[i] / 3, b, c;
                //计算根据第一场x的不同情况,计算4中情况对应的第一场第二场的分数
                GetABC(i, a, &b, &c, d1, d2);
                if (0 <= b && b <= k && 0 <= c && c <= k)
                {
                    LL maxNum = max(a, max(b, c));
                    LL diff = 3 * maxNum - a - b - c;
                    //剩下的场次,若先让最小的两个都抹平达到最大的一个分数,剩下的分数要是能平分给3队即可
                    if (n - k - diff >= 0 && (n - k - diff) % 3 == 0)
                    {
                        flag = true;
                        break;
                    }
                }
            }
        }
        if(flag)
            printf("yes\n");
        else
            printf("no\n");
    }
    return 0;
}
 

发表于 2018-10-05 11:39:32 回复(0)
本来想挣扎看看有没有啥简便的方法,结果最后还是屈服于暴力。
一共四种情况,罗列出来,对应的情况写在批注里了。
ps.这个数据范围int会超,一开始没考虑这个然后WA了个样例在那儿查了半天……下次可长点心吧……
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
int main()
{
    long long t;
    cin>>t;
    long long n,k,d1,d2;
    while(t--) {
        cin>>n>>k>>d1>>d2;
        long long x=n-k;
        if(x==0){
            if(d1==0 && d2==0) {
                cout<<"yes"<<endl;
            }else
                cout<<"no"<<endl;
            continue;
        }
        //!!!!!因为目前一共只打了k场,所以x1+x2+x3==k
        if(k-2*d1-d2>=0 && (k-2*d1-d2)%3==0 && (x-(2*d2+d1))>=0 && (x-(2*d2+d1))%3==0) { 
        //第一种情况x1<=x2<=x3
        //此时x1+x2+x3=x1+(x1+d1)+(x1+d1+d2)=3x1+2d1+d2==k,因为x1=(k-2*d1-d2)/3,
            //x-(2*d2+d1)为三队追平比分需要的场数,后面如有多余需要均分给三队
           cout<<"yes"<<endl;
        } else if(k-2*d1+d2>=0 && (k-2*d1+d2)%3==0 && (x-d1-d2)>=0 && (x-d1-d2)%3==0) {
            //第二种情况x1<=x2,x2>=x3,即x2=x1+d1,x3=x2-d2=x1+d1-d2
            //此时x1+x2+x3=3x1+2d1-d2=k
            //若要追平,需要d1+d2场,后面如有多余要均分给三队
            cout<<"yes"<<endl;
        } else if(k+2*d1-d2>=0 && (k+2*d1-d2)%3==0 && (x-max(d1,d2)-abs(d1-d2))>=0 && (x-max(d1,d2)-abs(d1-d2))%3==0) {
            //第三种情况,x1>=x2,x2<=x3,即x2=x1-d1,x3=x2+d2=x1-d1+d2
            cout<<"yes"<<endl;
        }else if(k+2*d1+d2>=0 && (k+2*d1+d2)%3==0 && (x-(2*d1+d2))>=0 && (x-(2*d1+d2))%3==0) {
            //第四种情况,x1>=x2,x2>=x3,即x2=x1-d1,x3=x2-d2=x1-d1-d2
            cout<<"yes"<<endl;
        }else
            cout<<"no"<<endl;
    }
    return 0;
}
发表于 2021-04-25 21:16:15 回复(0)
题目中只说队伍之间相差的分数,并没有说哪支队伍得分多,哪支队伍得分少。所以,本题应该分4种情况讨论。假设球队1得分为m (m >= 0) ,至少需要need 场比赛才能持平。

当 球队1< 球队2,球队2<球队3 时,得分情况:
        球队1:m
        球队2:m + d1
        球队3:m + d1 + d2 。此时有3 * m = k - d1 - d1 - d2    need = d1 + d2 + d2(此时球队3得分最多,所以球队1还需要赢d1 + d2场,球队2还需要赢d2场)

当 球队1< 球队2,球队2>球队3 时,得分情况:
        球队1:m
        球队2:m + d1
        球队3:m + d1 - d2 。此时有3 * m = k - d1 - d1 + d2    need = d1 + d2 (此时球队2得分最多,所以球队1还需要赢d1场,球队3还需要赢d2场)

当 球队1> 球队2,球队2>球队3 时,得分情况:
        球队1:m
        球队2:m - d1
        球队3:m - d1 - d2 。此时有3 * m = k + d1 + d1 + d2    need = d1 + d1 + d2 (此时球队1得分最多,所以球队2还需要赢d1场,球队3还需要赢d1 + d2场)

当 球队1> 球队2,球队2<球队3 时,得分情况:
        球队1:m
        球队2:m - d1
        球队3:m - d1 + d2 。
        此时有3 * m = k + d1 + d1 - d2  。这时不能确定哪个球队得分最多,还要分情况:
                    当 d1  >= d2 时,球队1得分最多need = d1 + d1 - d2
                    当 d1  <   d2 时,球队3得分最多need = d2 - d1 + d2

但是写代码时,不能用if   else if  else if....这种结构,因为同一组数据可能满足两种以上的情况,所以要把这几种情况都判断一遍,如果都不能输出yes,那么最后输出no

#include <iostream>

using namespace std;

int main(int argc, char *argv[])
{
    int t;
    long int n, k, d1, d2, tmp ,left;
    
    cin >> t;
    while(t > 0)
    {
        t--;
        cin >> n >> k >> d1 >> d2;
        
        tmp = k - d1 - d1 - d2; //球队1< 球队2,球队2<球队3        
        if(tmp >= 0 && tmp % 3 == 0) //球队1的得分有解是大前提
        {
            left = (n - k) - (d1 + d2 + d2);
            if(left >= 0 && left % 3 == 0)//剩下的场次不小于need,并且可以均分3场。
            {
                cout << "yes" << endl;
                continue;
            }
        }
        
        tmp = k - d1 - d1 + d2; //球队1< 球队2,球队2>球队3
        if(tmp >= 0 && tmp % 3 == 0)
        {
            left = (n - k) - (d1 + d2);
            if(left >= 0 && left % 3 == 0)
            {
                cout << "yes" << endl;
                continue;
            }
        }
        
        tmp = k + d1 + d1 + d2;//球队1> 球队2,球队2>球队3
        if(tmp >= 0 && tmp % 3 == 0)
        {
            left = (n - k) - (d1 + d1 + d2);
            if(left >= 0 && left % 3 == 0)
            {
                cout << "yes" << endl;
                continue;
            }
        }
        
        tmp = k + d1 + d1 - d2;//球队1>球队2,球队2<球队3
        if(tmp >= 0 && tmp % 3 == 0)
        {
            if(d1 >= d2)
            {
                left = (n - k) - (d1 + d1 - d2);
            }
            else 
            {
                left = (n - k) - (d2 + d2 - d1);
            }
            if(left >= 0 && left % 3 == 0)
            {
                cout << "yes" << endl;
                continue;
            }
        }
        
        cout << "no" << endl;
    }
    
    return 0;
}



编辑于 2019-01-24 23:41:22 回复(12)
不知道
发表于 2018-10-06 09:54:20 回复(0)
解方程:

枚举 d1,d2 的符号求出 a,b,c 的值。
不合法情况:
a<0,b<0,c<0;
n 不是 3 的倍数;
求完 a,b,c 它们的和不等于 k;
a>n/3,b>n/3,c>n/3
#include <bits/stdc++.h>
#define QAQ 0x3f3f3f3f
using namespace std;
int main()
{
    long long t,n,k,d1,d2,a,b,c;
    scanf("%lld",&t);
    while(t--)
    {
        scanf("%lld %lld %lld %lld",&n,&k,&d1,&d2);
        if(n%3!=0)
        {
            printf("no\n");
            continue;
        }
        int flag=0;
        for(int i=-1;1>=i;i=i+2)
        {
            for(int i1=-1;1>=i1;i1=i1+2)
            {
                long long d11=d1*i;
                long long d22=d2*i1;
                a=(k-2*d11+d22)/3;
                b=(k+d11+d22)/3;
                c=(k+d11-2*d22)/3;
                if(a+b+c!=k||a<0||b<0||c<0)
                {
                    continue;
                }
                if(a>n/3||b>n/3||c>n/3)
                {
                    continue;
                }
                printf("yes\n");
                flag=1;
                break;
            }
            if(flag==1)break;
        }
        if(flag==0)
        printf("no\n");
    }
    return 0;
}
/*
a = (k-2*d1+d2)/3
 
b = (k+d1+d2)/3
 
c = (k+d1-2*d2)/3
*/

发表于 2019-04-08 15:00:35 回复(3)
为什么6 3 3 0 是no

发表于 2019-06-03 20:17:39 回复(4)
比赛场次能被3整除且当前球队最高分小于等于n/3,则有可能踢平,步骤:
1、n是否能被3整除,否输出no,是进行2
2、求满足(k,d1,d2)的所有最大得分的最小值
3、如果这个最小值≤n/3,输出yes,否则输出no

发表于 2018-10-04 15:35:17 回复(3)
我有个问题,测试用例的3332不是在扯淡么,k=3说明一共就比了三场,怎么做到d1为3(说明有一个至少是3)的基础上d2为2,意思是只考虑n-k??
发表于 2020-08-08 00:08:11 回复(0)
首先考虑试题,失败不扣分,没有平局,赢了加1分,则总分就是N,如果N不能被3整除,则不能平局
然后考虑分差,如果剩余比赛(N-K)不足以弥补分差(d1+d2)那就肯定不能平局。
在考虑剩下的情况,如果是平局则每个球队得分应该都是N/3,如果其中一个球队得分大于N/3,则不能平局。
试题转换为判断当前比赛有没有球队得分超过N/3;
设最少得分的球队为M,
则三队得分有4种可能:
M,M+d1,M+d2+d1;
M,M+d2,M+d2+d1;
M,M+d1,M+d2;
M,M+d1,M+d1-d2;(假设d1大于d2)
求出M的值(M需要满足大于等于0,能被三整除),然后就可以计算出得分最高的球队,如果最高得分不高于N/3,则就算成功
(如果多个情况都满足条件,则其中有一个可以满足就行)
import java.util.Scanner;
public clas***ain {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int N = in.nextInt();
        for (int i = 0; i < N; i++) 
        { 
            if (jump(in.nextLong(), in.nextLong(), in.nextLong(), in.nextLong())) { System.out.println("yes"); } else { System.out.println("no"); } } } public static boolean jump(Long n, Long k, Long d1, Long d2) { if (n % 3 != 0 || k > n - d1 - d2) {
                return false;
        }
        Long max = d1 > d2 ? d1 : d2;
        Long min = d1 > d2 ? d2 : d1;
        Long m1 = k - 2 * d1 - d2;
        Long m2 = k - 2 * d2 - d1;
        Long m3 = k - d1 - d2;
        Long m4 = k - 2*max + min;
        if ((m1 >=0 && m1 % 3 == 0 && m1/3 + d1 + d2 <= n / 3) 
               || (m2 >=0 && m2 % 3 == 0 && m2/3 + d1 + d2 <= n / 3) 
                  || (m3 >=0 && m3 % 3 ==0 && m3/3 + max <= n / 3) 
                     || (m4 >= 0 && m4 % 3 ==0 && m4/3 + max > 0) )
        {
            return true;
        }
        return false;
    }
}

编辑于 2019-05-19 20:00:38 回复(0)
好家伙,几行就能解决的问题你们怎么都写这么多,我看了一眼看傻了
if (n % 3 != 0 || ((n - k) - (d1 + d2)) < 0 || (n / 3 - d1) < 0 || (n / 3 - d2) < 0) { printf("no\n"); continue; }
if (((n - k) - (d1 + 2 * d2))%3==0 || ((n - k) -(d2 + 2 * d1))%3==0 || ((n - k) -(d1 + d2))%3==0) printf("yes\n");
else printf("no\n");


发表于 2021-03-05 12:34:40 回复(1)
#include <bits/stdc++.h>
using namespace std;

bool F(long m, long k, long x, long y, long z){
    if(x<0 || y<0 || z<0)
        return 0;
    long s=x+y+z, Max = max(x, max(y, z));
    return (s<=k && (k-s)%3==0 && (3*Max-s)<=m && (m-(3*Max-s))%3==0);
}

int main(){
    int T;
    long n, k, d1, d2;
    scanf("%d", &T);
    while(T--){
        scanf("%ld%ld%ld%ld", &n, &k, &d1, &d2);
        long m = n - k;
        bool r = 0;
        r |= F(m, k, 0, d1, d1+d2);
        r |= F(m, k, 0, d1, d1-d2);
        r |= F(m, k, d1, 0, d2);
        r |= F(m, k, d1+d2, d2, 0);
        r |= F(m, k, d2-d1, d2, 0);
        printf("%s\n", r?"yes":"no");
    }
    return 0;
}

发表于 2020-12-04 00:02:04 回复(0)
用java的同学注意要用long来存储出现的数据,否则只能通过40%
发表于 2020-08-21 15:07:37 回复(0)
// 我都没创建数组,却总是提醒我数组越界  心态爆炸  求好心人解答
import java.util.*;
public class Main{
    public static void main(String[] args){
        try(Scanner in = new Scanner(System.in)){
            int t = in.nextInt(),i = 0;
            while(i < t){
                long n = in.nextLong();
                int k = in.nextInt(),d1 = in.nextInt(),d2 = in.nextInt();
                System.out.println(getResult(n,k,d1,d2));
                i++;
            }
        }
    }
    public static String getResult(long n,int k,int d1,int d2){
        int x11 = 0,x12 = 0,x13 = 0,x21 = 0,x22 = 0,x23 = 0,x31 = 0,x32 = 0,x33 = 0,x41 = 0,x42 = 0,x43 = 0;
        boolean tag1 = false,tag2 = false,tag3 = false,tag4 = false;
        if((k + d2 - d1) / 3 == (k + d2 - d1) / 3.0){
            x12 = (k + d2 - d1) / 3;
            x11 = d1 + x12;
            x13 = x12 - d2;
            if(x11 >= x12 && x12 >= x13 && x13 >= 0 && x11 <= k) tag1 = true;
        }
        if((k - d2 - d1) / 3 == (k - d2 - d1) / 3.0){
            x22 = (k - d2 - d1) / 3;
            x21 = d1 + x22;
            x23 = x22 + d2;
            if(x21 >= x22 && x23 >= x22 && x22 >= 0 && x21 <= k && x23 <= k) tag2 = true;
        }
        if((k + d2 + d1) / 3 == (k + d2 + d1) / 3.0){
            x32 = (k + d2 + d1) / 3;
            x31 = x32 - d1;
            x33 = x32 - d2;
            if(x32 >= x31 && x32 >= x33 && x33 >= 0 && x31 >= 0 && x32 <= k) tag3 = true;
        }
        if((k - d2 + d1) / 3 == (k - d2 + d1) / 3.0){
            x42 = (k - d2 + d1) / 3;
            x41 = x42 - d1;
            x43 = x42 - d2;
            if(x42 >= x41 && x43 >= x42 && x41 >= 0 && x43 <= k) tag4 = true;
        }
        if(tag1){
            int max = Math.max(Math.max(x11,x12),x13),c = Math.abs(max - x11) + Math.abs(max - x12) + Math.abs(max - x13);
            if(n - k >= c && (n - k - c) % 3 == 0) return "yes";
        }
        if(tag2){
            int max = Math.max(Math.max(x21,x22),x23),c = Math.abs(max - x21) + Math.abs(max - x22) + Math.abs(max - x23);
            if(n - k >= c && (n - k - c) % 3 == 0) return "yes";
        }
        if(tag3){
            int max = Math.max(Math.max(x31,x32),x33),c = Math.abs(max - x31) + Math.abs(max - x32) + Math.abs(max - x33);
            if(n - k >= c && (n - k - c) % 3 == 0) return "yes";
        }
        if(tag4){
            int max = Math.max(Math.max(x41,x42),x43),c = Math.abs(max - x41) + Math.abs(max - x42) + Math.abs(max - x43);
            if(n - k >= c && (n - k - c) % 3 == 0) return "yes";
        }
        return "no";
    }
}


发表于 2019-02-23 21:02:32 回复(4)