//此为二分法
#include<iostream>
#include<fstream>
#include<cstdlib>
using namespace std;
ifstream fin("C:\\data11.in");
ofstream fout("C:\\data11.out");
int n;
int arr[1000000];
int equalsum[100];
int numkind,totalnum;
//signlesub和multisum是二分法的判据
inline int singlesub(int beg)
{
return (2*beg-n)*(arr[beg+1]-arr[beg]);
}
inline int multisub(int beg,int end)
{
int sum=0;
for(int i=beg;i<end;++i)
sum-=2*arr[i];
sum+=((2*end-2-n)*arr[end]-(2*beg-2-n)*arr[beg]);
return sum;
}
void sort()
{
int temp;
for(int i=1;i<=n;++i)
{
for(int j=i;j>0;--j)
{
if(arr[j]<arr[j-1])
{
temp=arr[j];
arr[j]=arr[j-1];
arr[j-1]=temp;
}
}
}
}
void SearchMin(int pos)
{
totalnum=1;
numkind=1;
int cnt=0;
equalsum[cnt++]=arr[pos];
for(int i=pos;singlesub(i)==0;++i)
{
++totalnum;
bool isExist=false;
for(int j=0;j<cnt;++j)
{
if(arr[i+1]==equalsum[j])
{
isExist=true;
break;
}
}
if(!isExist)
{
equalsum[cnt++]=arr[i+1];
++numkind;
}
}
}
//有另外的解法,但因太复杂而放弃
int GetMinPos()
{
int beg=1;
int end=n;
while(beg!=end&&end-1!=beg)
{
int ans=singlesub(beg);
int sub=multisub(beg,end);
if(ans<0||sub<0)
{
beg+=(end-beg)/2;
}
else
{
int temp=beg;
beg-=(end-beg)/2;
end=temp;
}
}
int ans=singlesub(beg);
if(ans<0)
beg=end;
return beg;
}
void MiddleNightDream()
{
arr[0]=0;
while(fin>>n)
{
int cnt=0;
while(cnt<n)
fin>>arr[++cnt];
sort();
int min=GetMinPos();
SearchMin(min);
fout<<arr[min]<<"\t"<<totalnum<<"\t"<<numkind<<endl;
}
}
int main()
{
MiddleNightDream();
return 0;
}
MidNight'sDream
最新推荐文章于 2022-04-07 14:53:37 发布