1. 程式人生 > 其它 >演算法題解----位元組跳動春招後端程式設計題

演算法題解----位元組跳動春招後端程式設計題

問題描述:

有三隻球隊,每隻球隊編號分別為球隊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