字节--踢球问题
字節–踢球問題
文章目錄
- 字節--踢球問題
- 一、題目描述
- 二、分析
- 三、代碼
一、題目描述
有三只球隊,每只球隊編號分別為球隊1,球隊2,球隊3,這三只球隊一共需要進行 n 場比賽。現在已經踢完了k場比賽,每場比賽不能打平,踢贏一場比賽得一分,輸了不得分不減分。已知球隊1和球隊2的比分相差d1分,球隊2和球隊3的比分相差d2分,每場比賽可以任意選擇兩只隊伍進行。求如果打完最后的 (n-k) 場比賽,有沒有可能三只球隊的分數打平。
- 輸入描述:
- 輸出描述:
二、分析
- 因為每場比賽不能打平,踢贏一場比賽得一分,輸了不得分不減分,所以這意味著,所有的比賽總分加起來一定是n,打了k場比賽,那么這k長比賽的總分是k;
- 要注意比賽場數(10^12)非常大,需要使用long long的類型。
- 解決這道題的關鍵在于得出三個隊伍的具體比分。
- 我們取一組數據n=150,k=31,d1=15,d2=17。 無論三個隊伍的比分最終是怎樣的,總是有四種情況
- 下一個問題是怎么知道三個隊伍的具體得分,也就是得出unknow的值
- 這非常簡單,由于三個隊伍的總分k(即總比賽場數,注意每一局只有人得分沒有人扣分)是知道的,因此很容易得出unknow的值,接著判斷unknow是不是整數,以及要保證三個隊伍的得分為正。
- 得出三個隊伍的具體分數后,就可以根據剩余場數n-k進行判斷
例如剩余場數150 - 31 = 119 119 - (22 - 7) - (22 - 5) = 87
由于87是三的倍數,這剩下的87場比賽可以讓3個隊伍平均分得分。
因此是有可能平均的。
三、代碼
#include<iostream> using namespace std;//n代表總場數 //k代表已經進行的場數 //t1代表隊伍1的分數 //... //... bool check(long long n,long long k,long long t1,long long t2,long long t3) {//如果已經進行了k場所獲的的k分,反而不能被3整除,直接返回false//就是4種情況中的前兩種情況if((k - t1 - t2 - t3) % 3 != 0){return false;}else{//相當于求得表中的unknowlong long temp = (k - t1 - t2 - t3) / 3;//求得每個隊伍經過k場后的真實得分的t1 += temp;t2 += temp;t3 += temp;//如果出現某個隊伍的分數為負,直接返回if(t1 < 0 || t2 < 0 || t3 < 0){return false;}else{//獲取3個隊伍當中最大的分數long long max;max = t1 > t2 ? t1 : t2;max = max > t3 ? max : t3;//求把剩下兩個分數較小的隊伍補齊到和最大分數的隊伍所需的分數long long need_remain = 3 * max - t1 - t2 - t3;//n場還剩下的場數,也就是待均分的分數long long remain = n - k;//判斷剩余場數能不能打贏,如果剩下的分數能被3個隊伍均分直接返回true,反之返回false if(need_remain <= remain && (remain - need_remain) % 3 == 0) return true;else{return false;}}} }int main() {long long t;cin >> t;long long n,k,d1,d2;while(t--){cin >> n >> k >> d1 >> d2;//判斷四種情況下每種平局的可能性,只要有一種可能性成立即可 if(check(n,k,d1,0,d2) || check(n,k,d1,0,-d2)||check(n,k,-d1,0,d2)||check(n,k,-d1,0,-d2))cout << "yes"<<endl;else cout << "no"<<endl;}return 0; }總結