一个有 n 个整数的数组 a,n是一个奇数。
每次可以选择数组里的一个元素 ai 并把这个元素加上 1。
在至多 k 次操作之后,数组的中位数最大能变成多少。
输入格式:
多组输入
第一行两个整数 n,k(1≤n≤2×105,1≤k≤109)。
第二行 n 和整数 a1,a2,......,an。
输出格式:
k 次操作后数组的中位数。
输入样例:
3 2
1 3 5
输出样例:
5
首先,用最普通的想法就是从中位数开始往后一个数一个数地找找到可以实现的最大中位数的值;第二种方法用二分法来枚举中位数,看是否可行;这个题注意ai的范围没有说明,可能超过int范围,所以记得用long long
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+10;
ll a[maxn],b[maxn];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int n,k;
while(cin>>n>>k)
{
for(int x=1;x<=n;x++)
{
cin>>a[x];
}
sort(a+1,a+n+1);
ll z=(n+1)/2;
for(int x=z;x<n;x++)
{
b[x+1]=a[x+1]-a[x];
}
ll ans=a[z],w=1;
while(k>0)
{
if(k-b[z+w]*w>=0&&z+w<=n)
{
k-=b[z+w]*w;
//cout<<k<<endl;
ans=a[z+w];
w++;
}
else
{
ans+=k/w;
break;
}
}
cout<<ans<<endl;
}
}
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <vector>
#include <string>
using namespace std;
#define int long long
int x[200010];
signed main()
{
int n,k;
while(~scanf("%d %d",&n,&k))
{
for(int i=0;i<n;i++)
{
scanf("%d",&x[i]);
}
sort(x,x+n);
int l=x[n/2],r=x[n-1]+k/(n/2+1);
int mid=(l+r)/2;
//int ans;
while(l<=r)
{
int t=k;
for(int i=n/2;x[i]<mid && i<n;i++)
{
t-=(mid-x[i]);
if(t<0)
{
break;
}
}
if(t<0)
{
r=mid-1;
mid=(l+r)/2;
} else
{
//ans=mid;
l=mid+1;
mid=(l+r)/2;
}
//printf("%d %d %d\n",l,r,mid);
}
printf("%d\n",l-1);
}
return 0;
}