poj-3579 Median

呂振麒 bio photo By 呂振麒 Comment

傳送門:

Median

思路:

這類型的題目解法都是先確定好答案的上下界之後去二分搜,第K大表示此數比K-1個數大,仔細思考如何使二分搜最終得到此答案即可。

code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
ll N, tar;
vi arr;
void init(){
  int tmp;
  arr.clear();
  for(int i=0;i<N;i++){
    tmp = getint();
    arr.PB(tmp);
  }
  tar = (N * (N-1))>>1;
  tar = (tar-1)>>1; // 中位數前有幾個數字
}
int l,r,cnt;

inline bool suc(ll p){
  l=0, r=0, cnt=0;
  while(r+1<N){
    if(r<l or arr[r+1] - arr[l] < p) 
      ++r;
    else{
      cnt += (r-l);
      ++l;
    }
  }
  cnt += ((r-l+1)*(r-l))>>1;
  return cnt<=tar;
}

int sol(){
  int L=INT_MAX, R;
  sort(arr.begin(), arr.end());
  R = arr.back() - arr[0];
  for( int i=1;i<N;i++ )
    L = min ( L, arr[i] - arr[i-1]);

#define mid ((L+R)/2)
  while(R-L>1) suc(mid) ? L=mid : R=mid;
  return L;
}

int main(){
  while(cin>>N){
    init();
    cout << sol() << endl;
  }
}
comments powered by Disqus