Week4 C-TT的神秘礼物

题目大意:

TT 是一位重度爱猫人士,每日沉溺于 B 站上的猫咪频道。

有一天,TT 的好友 ZJM 决定交给 TT 一个难题,如果 TT 能够解决这个难题,ZJM 就会买一只可爱猫咪送给 TT。

任务内容是,给定一个 N 个数的数组 cat[i],并用这个数组生成一个新数组 ans[i]。新数组定义为对于任意的 i, j 且 i != j,均有 ans[] = abs(cat[i] - cat[j]),1 <= i < j <= N。试求出这个新数组的中位数,中位数即为排序之后 (len+1)/2 位置对应的数字,'/' 为下取整。

TT 非常想得到那只可爱的猫咪,你能帮帮他吗?

Input

多组输入,每次输入一个 N,表示有 N 个数,之后输入一个长度为 N 的序列 cat, cat[i] <= 1e9 , 3 <= n <= 1e5

Output

输出新数组 ans 的中位数

Sample Input

4
1 3 2 4
3
1 10 2

Sample Output

1
8

思路:两次二分-淋漓尽致

这道题目知道是用二分的思想做,但是做的时候却卡了好几天,怎么二分呢?
这个时候就要回到中位数的定义中去:大小排序后最中间位置,即(n*(n-1)/2+1)/2
新数组中最大数为原数组中最大数与最小数之差,然后可以对这个值二分。要判断其在新数组中的位置,即找在新数组中有多少比他大或小。
这一步又要用到二分的思想,对于固定的数,找满足条件的数的个数(原数组二分 找满足差的个数 )
 1 /*
 2     Name: 
 3     Copyright: 
 4     Author:sduAllen 
 5     Date: 19/03/20 11:44
 6     Description: 
 7 */
 8 
 9 #include<iostream>
10 #include<stdio.h>
11 #include<algorithm>
12 #include<cmath>
13 using namespace std;
14 
15 //const int max = 1e5+1;
16 int *cat = new int[100001];
17 int N;
18 int last_index(int start){ //找到最后一个满足小于等于start的位置索引 
19     int l=0,r=N-1,index=-1;
20     while(l<=r){
21         int mid = (l+r)/2;
22         if(cat[mid]<=start){
23             index=mid;
24             l=mid+1;
25         }
26         else
27             r=mid-1;
28     }
29     return index;
30 }
31 
32 int main(){ 
33     
34     while(scanf("%d",&N)!= EOF){
35         for(int i=0;i<N;i++)
36         scanf("%d",&cat[i]);
37         sort(cat,cat+N);
38         
39         int ans_Mid = (N*(N-1)/2+1)/2; 
40         int themid;
41         int l=0,r=cat[N-1]-cat[0];    //新数组的最大最小值    
42     
43         while(l<=r){   //在0~max之间二分 
44             int cnt = 0,mid = (l+r)/2;    //cnt计算在新数组中的位置 
45             for(int i=0;i<N;i++){
46                 int index = last_index(cat[i]+mid);
47                 if(index!=-1)
48                 cnt += index-i;
49             }
50             if(cnt >= ans_Mid){
51                 themid = mid;
52                 r=mid-1;
53             }
54             else
55                 l=mid+1;
56         }
57         printf("%d
",themid);        
58     }
59     return 0;    
60 }



流转星云
原文地址:https://www.cnblogs.com/liuzhuan-xingyun/p/12529698.html