Tema: TT - el don misterioso
que Italia:
TT es un amantes de los gatos graves, canal de gato en el complacer a diario en la estación B.
Un día, un amigo ZJM decidió TT TT un problema, si TT puede resolver este problema, ZJM va a comprar un lindo gato dio TT.
Resumen Se da array gato [i] un número N, y generar una nueva ans array [i] con la matriz. Se define como la nueva matriz para cualquier i, j e i = j, son ans [] = abs (cat [ i] - gato [j]) !, 1 <= i <j <= N. Esta nueva matriz. Determinar la mediana, a continuación, la mediana es la especie (LEN + 1) / 2 que corresponde al número de posición, '/' es un redondeo.
TT deseando desesperadamente gato lindo pájaro, ¿puedes ayudarlo? ~
Entrada:
múltiples conjuntos de entradas, cada entrada de un N, el número N expresado, después de la entrada de una secuencia de gato longitud N, gato [i] <= 1E9, 3 <= n <= 1E5 ~
Salida:
salida de nueva matriz ans mediana ~
Ejemplo:
Ideas de resolución de problemas: En primer lugar, la violencia, O (n2) a blanco (violencia también es posible, CSP podría quedar salpicado, por supuesto, a vj blanca a la derecha). A continuación, la optimización; primero, la clasificación de la matriz original, por lo que debe XJ-xi es mayor que 0; el uso después de xj-xi <= p, encontrar el dos puntos p, encuentra que hay varios satisface xj desigualdad (enumeración XI), cuando hay xj (n * (n-1) / 2 + 1) / 2 º cuando p se ha descrito distancia cerca de la mediana (probablemente menor que la mediana, pero son más pequeños que p (lEN + 1) / 2, cuando p no es la mediana, debe seguir aumentando hasta el último 1 p, más la condición no se cumple, entonces p es la mediana). Por supuesto, el proceso de búsqueda es ser XJ dicotomía, que es aproximadamente el tiempo de complejidad O (+ nlogn nlogn * log n);
código:
#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);
}
}