1. 程式人生 > >2017CCPC 哈爾濱 B

2017CCPC 哈爾濱 B

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