Programming thinking week4 homework mystery gift of C-TT

topic

TT is a serious cat lover who indulges in the cat channel on station B every day.
One day, TT's friend ZJM decided to give TT a problem. If TT can solve this problem, ZJM will buy a cute cat and give it to TT.
The task content is, given an N number array cat [i], and use this array to generate a new array ans [i]. The new array is defined as for any i, j and i! = J, all have ans [] = abs (cat [i]-cat [j]), 1 <= i <j <= N. Try to find the median of this new array. The median is the number corresponding to the (len + 1) / 2 position after sorting, and '/' is rounded down.

Input

Multiple sets of input, each time enter an N, indicating that there are N numbers, and then enter a sequence cat of length N, cat [i] <= 1e9, 3 <= n <= 1e5.

Output

Output the median of the new array ans.

Sample Input

4
1 3 2 4
3
1 10 2

Sample Output

1
8

Ideas

The meaning of the problem is that, given an array cat [], choose two of the numbers to make a difference, and find the absolute value, the absolute value of all the differences form a new array ans [], find the median of ans [] . Because | ab | = | ba |, the problem can be converted to sort cat [] in ascending order, any j> i, find cat [j] -cat [i], form ans [], and find the median.
The brute force method is to calculate the array ans [] and find the median, the complexity is O (n ^ 2), which is unacceptable.
Since the number n of the elements in the cat [] array is known, the number of elements in the ans [] array is n * (n-1) / 2, that is, the subscript pos = ( (n-1) * n / 2 + 1) / 2. In this way, the solution process can be achieved with two dichotomies.
In the first dichotomy, find the median. Let the left boundary l be 1, and the right boundary r be the largest value in ans, namely cat [n-1] -cat [0]. When l <r, loop, mid = (l + r) / 2, if the rank of mid is less than or equal to the median of ans [], then l = mid + 1, rslt = mid; otherwise r = mid-1. In the cycle, ans does not necessarily exist in ans [], but by continuously moving the left and right boundaries to approximate, at the end of the loop, rslt must be fixed as a number present in ans []. For example, a sequence in ans [] is a, b, c, where b is the median, then for numbers belonging to (0, a), its ranking is less than pos; for numbers belonging to (a, b), Its ranking is equal to pos; for numbers belonging to (a, + inf), its ranking is greater than pos. So update rslt when <=. The
second dichotomy process finds the ranking. Obviously, in the above process, because it cannot be directly obtained ans [], you need to design a function to find the rank of x in ans [], that is, calculate the logarithm of the binary tuple of cat [j] -cat [i] <x, and shift the term to get cat [j] <cat [i ] + x. Enumerate subscript i, and calculate the number of subscript j that meet the conditions.

Code

#include <cstdio>
#include <algorithm>
using namespace std;

int n;
int cat[100005];

int Rank(int x){//查找x在ans[]的名次
    int rank=0;
    for(int i=0;i<n;i++){
        int l=i+1,r=n-1,ans=n;
        while(l<=r){
            int j=(l+r)/2;
            if(cat[j]<cat[i]+x){
                l=j+1;
            }
            else{
                r=j-1;
                ans=j;
            }
        }
        rank+=(ans-i-1);//去除cat[j]-cat[i]<=0的部分
    }
    return rank+1;
}

int find(){
    int l=1,r=cat[n-1]-cat[0],pos=((n-1)*n/2+1)/2,ans=0;
    while(l<=r){
        int mid=(l+r)/2;
        if(Rank(mid)<=pos){
            l=mid+1;
            ans=mid;
        }
        else{
            r=mid-1;
        }
    }
    return ans;
}

int main() {
    while(scanf("%d",&n)!=EOF){
        for(int i=0;i<n;i++){
            scanf("%d",&cat[i]);
        }
        sort(cat,cat+n);
        int ans=find();
        printf("%d\n",ans);
    }
    return 0;
}

Title link

Published 24 original articles · praised 2 · visits 435

Guess you like

Origin blog.csdn.net/weixin_43805228/article/details/104978717