2017CCPC 哈爾濱 B
阿新 • • 發佈:2018-10-02
clu pre mes += scanf 數加 答案 urn ++
這題沒有考慮到m這個東西,所以就沒有往二分答案的方向想
二分答案
check的時候,我們找的是大於等於x的數有多少個被加入到那個數組中。如果 >= m說明這個數可能是答案,否則就不是。
用尺取來計數,還算比較好理解。
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 int n,k; 6 long long m; 7 8 int a[100005]; 9 int b[100005]; 10 11 bool check(int x) { 12 13 long long ans = 0; 14 int num = 0; 15 int pos = 1; 16 17 for(int i = 1; i <= n; i++) { 18 if(a[i] >= x) { 19 num++; 20 } 21 if(num == k) { 22 23 // 後面形成的區間,x作為第k大,或者有比它大的 24 // 但是一定會有n - i + 1個大於等於x的數被加入到ans數組中 25 ans += n - i + 1;26 27 // 如果左端這個數小於x 28 // 那麽去掉他沒有影響 29 // 依然會有n - i + 1個大於等於x的數加入到ans數組中 30 while(a[pos] < x) { 31 ans += n - i + 1; 32 pos++; 33 } 34 pos++; 35 num--; 36 } 37 38 39 } 40 41//cout<<ans<<endl; 42 if(ans >= m) return true; 43 return false; 44 } 45 46 int main() { 47 48 int t; 49 scanf("%d",&t); 50 51 while(t--) { 52 scanf("%d %d %lld",&n,&k,&m); 53 54 for(int i = 1; i <= n; i++) { 55 scanf("%d",&a[i]); 56 } 57 58 //cout<<num<<endl; 59 int L = 1,R = 1000000001; 60 int mid; 61 while(R - L > 1) { 62 mid = L + R >> 1; 63 64 //cout<<mid<<‘ ‘<<b[mid]<<endl; 65 if(check(mid)) { 66 L = mid; 67 } 68 else { 69 R = mid; 70 } 71 } 72 73 74 printf("%d\n",L); 75 76 } 77 78 79 80 81 82 return 0; 83 }
2017CCPC 哈爾濱 B