競價
描述
輸入
輸出
數據范圍
樣例輸入
2
4 3 5
7 4 7
樣例輸出
Case #1: 0
Case #2: 1
這一題想了很久,思路基本都是對的,可惜最后還是放棄了沒提交,現在看了別人的代碼,理清了一下思路。n是寶石數目,a是Alice的錢幣數目,b是bob的錢幣數目。
基本就是去找規律,每次要獲取寶石,Alice和Bob都必須付出至少1個錢幣的代價。獲勝的條件是獲取超過寶石數目n的一半的寶石(n/2 + 1),考慮到Alice在最小代價下能獲取的寶石數目是a,那么Alice在此時最后到底能否獲勝呢?這個取決於n的大小,於是可以根據n的大小分成以下三種情況來考慮:
1.n > 2 * a;即n至少為2 * a + 1。自然會想到比較a和b的大小:
當b > a時,即b至少為a + 1,此時Bob必然獲勝,因為即便前面a個寶石全部讓給Alice,Bob依然可以獲取剩下的至少a+1個寶石;
當b < a時,Alice必然獲取,同上,因為即便前面b個寶石全部讓給bob,Alice依然可以獲取a個寶石,始終比bob的寶石多;
當b = a時,兩人買到的寶石一樣多。
2.n == 2 * a時,同上考慮:
當b < a時,Alice獲勝;
當 b >= 2 * a + 2時,bob獲勝,因為想要獲勝就必須獲取a + 1個寶石,因為Alice有a個寶石,Alice的最優策略是每次至少出1個錢幣,所以bob每次必須用2個錢幣才能獲取一個寶石,所以即b至少為2*(a+1)時bob獲勝;
當b >= a && b < 2*a + 2時,兩人最終獲取的寶石一樣多;
3.當n < 2 * a時,此時情況最復雜,我當時就是被這里的細節給嚇暈了,根據n的奇偶性分成兩種情況:
當n是奇數時,獲勝需要的寶石數目是winner = n/2 + 1,因為a > n / 2,所以a的數目至少是等於winner,Alice的想要獲勝(即拿到winner個寶石)的最優策略是每次用d = a / winner的錢幣來獲取一個寶石,bob必勝的情況是每次都付出比Alice的報價多1個(即d + 1個),所以bob至少需要(d + 1) * winner才能保證必勝,所以當b >= (d+1)*winner時,bob必勝;否則的話,Alice必勝。
當n是偶數時,獲勝的寶石數目winner2 = n / 2 + 1,平局(即兩人拿到的寶石一樣多)需要寶石數目是winner1 = n / 2,同樣為了拿到winner2個寶石Alice每次付出d2 = a / winner2,為了拿到winner1個寶石Alice每次付出d1 = a / winner1,bob必勝的策略是每次付出(d1 + 1)拿到winner2個寶石,即當b >= (d1+1)*winner2時,bob必勝;Alice必勝的時候則是b< (d2 + 1) * winner1,即bob無法獲得至少一半的寶石;當b>= (d2+1) * winner1 && b < (d1+1)*winner2時,兩人獲取的寶石一樣多。
問題分析清楚之后,代碼就很好寫了,而且小數據和大數據都可以順利AC!
1 #include<iostream> 2 using namespace std; 3 int main() { 4 int T; 5 cin >> T; 6 int n, a, b; 7 int k = 0; 8 while(T--) { 9 cin >> n; 10 cin >> a; 11 cin >> b; 12 int result; 13 cout << "Case #"; 14 cout << ++k; 15 cout << ": "; 16 if (n > 2 * a) { 17 if (b > a) 18 result = -1; 19 if (b == a) 20 result = 0; 21 if (b < a) 22 result = 1; 23 cout << result << endl; 24 continue; 25 } 26 if (n == 2 * a) { 27 if (b < a) 28 result = 1; 29 if (b >= a && b <= 2 * a + 1) 30 result = 0; 31 if (b > 2 * a + 1) 32 result = -1; 33 cout << result << endl; 34 continue; 35 } 36 if (n < 2 * a) { 37 if (n % 2 == 0) { 38 int temp1 = n / 2; 39 int temp2 = n / 2 + 1; 40 int d1 = a / temp1; 41 int d2 = a / temp2; 42 int smaller = (d2 + 1) * temp1; 43 int bigger = (d1 + 1) * temp2; 44 if (b < smaller) 45 result = 1; 46 if (b >= bigger) 47 result = -1; 48 if (b >= smaller && b <bigger) 49 result = 0; 50 } 51 else { 52 int temp = n / 2 + 1; 53 int d = a / temp; 54 int bigger = (d + 1) * temp; 55 if (b >= bigger) 56 result = -1; 57 else 58 result = 1; 59 } 60 cout << result << endl; 61 } 62 } 63 return 0; 64 }