Codeforces Round #733 (Div. 1 + Div. 2) C. Pursuit
阿新 • • 發佈:2021-07-18
C. Pursuit
題意:
給t組樣例 每組樣例給n個數 a[1] , a[2] , a[3] ...... a[n] b[1] , b[2] , b[3] ...... b[n] 資料保證(0 <= a[i] , b[i] <= 100 , t組樣例n的總和小於1e5) a[i]表示第一個人在i這個階段的分數 b[i]表示第二個人在i這個階段的分數 現在只給了n個階段每個人的分數 後面若干個階段的分數值0到100之間都有可能 現在定義一個人在i這個階段的得分為 從i個分數中取出 i - i / 4 個最大的分數相加即為 在i階段的分數 問在n這個階段是否第一個人的得分大於第二個人的得分 如果可以輸出0 如果不行輸出最少加幾個階段 使得第一個人的得分大於等於第二個人的得分
思路:
既然要讓a的分數要大於等於b的分數
那麼a[n+1] , a[n+2] , a[n+3] ......都應該是100
b[n+1] , b[n+2] , b[n+3] ....... 都應該是0
所以從大到小排序之後
用字首和優化到on
on列舉o1判斷即可
時間複雜度:O n
#include<bits/stdc++.h> #define fer(i,a,b) for(re i = a ; i <= b ; ++ i) #define re register int #define pll pair<int,int> #define x first #define y second #define sf(x) scanf("%d",&x) #define sfl(x) scanf("%lld",&x) typedef long long ll ; using namespace std; const int N = 1e6 + 10 , M = 2010 , inf = 0x3f3f3f3f , mod = 1e9 + 7 ; int t ; int n ; int a[N] , b[N] ; int s[N] , h[N] ; int main() { cin >> t ; while(t--) { cin >> n ; fer(i,1,n) { sf(a[i]) ; } fer(i,1,n) { sf(b[i]) ; } sort(a + 1 , a + 1 + n) ; sort(b + 1 , b + 1 + n) ; reverse(a + 1 , a + 1 + n) ; reverse(b + 1 , b + 1 + n) ; fer(i,1,n) { s[i] = s[i-1] + a[i] ; } fer(i,1,n) { h[i] = h[i-1] + b[i] ; } fer(i,n+1,3e5) { s[i] = s[i-1] + 100 ; } fer(i,n+1,3e5) { h[i] = h[i-1] ; } if(s[n-n/4] >= h[n-n/4]) { puts("0") ; } else { for(int i = n + 1 ; i <= N ; i ++) { int j = i - i / 4 ; // j為取多少個最大的個數 int z = i - n ; // z為有多少個多餘的100可以取 int s1 , s2 ; if(z <= j) s1 = 100 * z + s[j-z] ; else s1 = 100 * j ; s2 = h[j] ; if(s1 >= s2) { cout << i - n << "\n" ; break ; } } } } return 0; }