问题描述
主油管道为东西向,确定主油管道的南北位置,使南北向油井喷油管道和最小。要求线性时间完成。
1<= 油井数量 <=2 000 000
输入要求:
输入有油井数量行,第 K 行为第 K 油井的坐标 X ,Y 。其中, 0<=X<2^31,0<=Y<2^31 。
输出要求:
输出有一行, N 为主管道最优位置的最小值
注意:用快排做的不给分!!
友情提示:可以采用while(scanf("%d,%d",&x,&y) != EOF)的数据读入方式。
测试输入 | 期待的输出 | 时间限制 | 内存限制 | 额外进程 | |
---|---|---|---|---|---|
测试用例 1 | 以文本方式显示
| 以文本方式显示
| 1秒 | 64M | 0 |
问题分析
由于本篇参考的博客写的真的很全很好很易懂,所以在此不再赘述,详情请看参考博客。
问题解决
#include <iostream>
#include <algorithm>
#define N 2000020
using namespace std;
long long y[N],cc=0;
void change(long long a[],long long x,long long y)
{
long long tt;
tt=a[x];
a[x]=a[y];
a[y]=tt;
}
void Insert(long long a[],long long begin,long long end) //直接插入排序
{
for(long long i=begin;i<=end;i++)
{
long long t=a[i];
long long mark=i;
if(a[i]<a[i-1]&&i>=begin+1)
{
while(a[mark-1]>t)
{
a[mark]=a[mark-1];
mark--;
}
a[mark]=t;
}
}
}
long long Middle(long long a[],long long b,long long e)
{
long long count=0,i;
for(i=b;i+4<=e;i+=5)
{
Insert(a,i,i+4);
change(a,b+count,i+2); //把中位数换到前面
count++;
}
if(i<e) //剩余够不了一组的元素
{
Insert(a,i,e);
change(a,b+count,(i+e)/2);
count++;
}
if(count<=1) return a[b]; //递归出口,组内元素个数很少时,中位数近似取第一个
return Middle(a,b,b+count-1);//递归调用
}
long long Index(long long a[],long long b,long long e,long long o)
{
for(long long i=b;i<e;i++)
{
if(a[i]==o)
return i;
}
}
long long Part(long long a[],long long b,long long e,long long obj)
{
long long loc=Index(a,b,e,obj);
change(a,loc,e);//把中位数换到最后一个位置
long long tt=a[e];
long long i=b,j=e-1;
while(i<j)
{
while(a[i]<tt) i++;
while(a[j]>tt) j--;
if(i<j) change(a,i,j);
}
//if(a[i]<tt) return e; //一定注意:单独考虑所有数都比中位数小的情况,不需要和最后一个交换
change(a,i,e);
return i;
}
long long Findlittle(long long a[],long long b,long long e,long long little)
{
long long mm=Middle(a,b,e);
long long site=Part(a,b,e,mm);
long long n = site-b+1;
if(n==little) return mm;
else if(little<n) return Findlittle(a,b,site-1,little);
else return Findlittle(a,site+1,e,little-n);
}
int main()
{
long long xi,yi;
while(scanf("%lld,%lld",&xi,&yi) != EOF)
{
y[cc++]=yi;
}
long long res=Findlittle(y,0,cc-1,(cc+1)/2);
cout<<res<<endl;
return 0;
}