Topic: TT - the mysterious gift
that Italy:
TT is a severe cat lovers, cat channel on the daily indulge in B station.
One day, a friend ZJM decided to TT TT a problem, if TT can solve this problem, ZJM will buy a cute cat gave TT.
SUMMARY is given array cat [i] a number N, and generate a new array ans [i] with the array. It is defined as the new array for any i, j and i = j, are ans [] = abs (cat [ i] - cat [j])!, 1 <= i <j <= N. This new array. Determine the median, then the median is the sort (len + 1) / 2 corresponding to the position number, '/' is a rounding.
TT desperately wanting bird cute cat, can you help him? ~
Input:
multiple sets of inputs, each input one N, the number N expressed, after the input of a sequence of length N cat, cat [i] <= 1e9, 3 <= n <= 1e5 ~
Output:
Output new array ans median ~
Example:
Problem-solving ideas: First of violence, O (n2) to white (violence also possible, csp could get dotted, of course, to vj white on the right). Then, the optimization; first, sorting the original array, so that it must xj-xi is greater than 0; the use after xj-xi <= p, find the two points p, find that there are several xj satisfies inequality (enumeration XI), when there xj (n * (n-1) / 2 + 1) / 2 th when p has been described distance close to the median (likely less than the median, but are smaller than p (len + 1) / 2, when p is not the median, must continue to increase until the last 1 p plus the condition is not satisfied, then p is the median). Of course, the search process is to be xj dichotomy, which is approximately the time complexity of O (nlogn + nlogn * logn);
Code:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
using namespace std;
int a[100005];
void gengxin()
{
memset(a,0,sizeof(a));
}
int panduan(int k,int n)
{
int total=0,m=n*(n-1)/2;
m=(m+1)/2;
for(int i=0;i<n-1;i++)//通过枚举xi找xj总个数
{
int h=a[i]+k;
int l=0,r=n;
while(l+1<r)//二分
{
int mid=(l+r)/2;
if(a[mid]>h)
{
r=mid;
}else
{
l=mid;
}
}
total=total+(l-i);
}
if(total>=m)//根据xj的总数返回不同的值,0说明p得小点,1说明p得大点
{
return 0;
}else
{
return 1;
}
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
gengxin();
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
sort(a,a+n);//排序
int l=0,r=a[n-1];
while(l+1<r)
{
int mid=(r+l)/2;
int flag=panduan(mid,n);
if(flag==0)//判断
{
r=mid;
}else
{
l=mid;
}
}
printf("%d\n",r);
}
}