Mysterious gift of Week4 C TT

Title description:

Given an array of N numbers 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.

Enter:

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

Sample Inpout:

4
1 3 2 4
3
1 10 2

Output:

Output the median of the new array ans

Sample Output:

1
8

Ideas:

For the input cat sequence, we can know the size of the processed array through the arithmetic sequence of sum of difference numbers, so that we can know the required median ranking, and we can know the number of numbers smaller than the median.
We sort the cat sequence in ascending order, then the ans array can be obtained by subtracting the previous number from the latter number, so that the absolute value can be removed, and we can also give the range of the median, that is, 0 to cat [n] -cat [1].
Because the answer is monotonic, we can consider the method of dichotomy, dichotomize the range of the median, and then rank it with the median according to the number P obtained by the dichotomy. If it is greater than the median, the median In the first half, continue to divide the first half, otherwise the second half.
The last problem is to determine how many numbers are less than P. We traverse i to find the range of j. The number of data less than P can be obtained as sum, and we can also find the number of data equal to P as equal. Note that the median ranking is m. If sum <m && (equal + sum)> = m, it means that P is the median. If equal + sum <m means that P is less than the median, then continue the second half of the median range. If P is greater than the median, continue the first half of the dichotomy until the median is obtained.

Code:

#include <iostream>
#include <algorithm>

using namespace std;

int find(int *v,int x,int n,int i)
{
	int l=i,r=n,ans=-1;
	while(l<=r)
	{
		int mid=(l+r)>>1;
		if(v[mid]<x)
		{
			ans=mid;
			l=mid+1;
		}
		else
			r=mid-1;
	}
	return ans;
}

int main()
{
	int n;
	while (scanf("%d",&n)!=EOF)
	{
		int *input = new int[n+1]();
		for (int i = 1; i <= n; i++)
			scanf("%d",&input[i]);
		sort(input + 1, input + n + 1);
		int l = 0, r = input[n] - input[1], mid = 0, m = ((n - 1)*n / 2 + 1) / 2, sum;
		while (l <= r)
		{
			int equal=0;
			sum=0;
			mid = (l + r) >> 1;
			for (int i = 1; i <= n; i++)
			{	
				int temp= find(input,input[i]+mid,n,i);
				if(temp!=-1)
				{
					for(int j=temp+1;j<=n&&input[j]==(input[i]+mid);j++)
						equal++;	
					sum += temp-i;
				}
				else
					for(int j=i+1;j<n&&input[j]==(input[i]+mid);j++)
						equal++;	
			}
			if(sum<m&&(equal+sum)>=m)
				break;
			else if(equal+sum<m)
				l=mid+1;
			else
				r=mid-1;
		}
		cout << mid << endl;
	}
    return 0; 
}
Published 32 original articles · praised 0 · visits 687

Guess you like

Origin blog.csdn.net/qq_43814559/article/details/104979036
TT