训练赛
思路:
欲维护f(x)使其最小,可知x应该是a1和an的中位数。
∵d[i]=|a[i]-x|
∴易推得欲维护min_f(k,x)即维护一个min_d[i]即可
故在(1,n-k)的范围内(因欲求的d[i]可转化为a[i+k]-a[i])维护d[i]的最小值,d[i]最小时可找到中位数X,利用此时的pos,易得中位数X。
https://blog.csdn.net/troubleshooter/article/details/25395225此法求中位数在2e5的数据范围及2e5的查询次数条件下有超时的可能性,根据上述思路简单建模模拟即可得出以下代码
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> using namespace std; const int maxn=2e5+7; int a[maxn]; int b[maxn]; int main() { int t; while(scanf("%d",&t)!=EOF) { while(t--) { int mid=0; int n,k; scanf("%d%d",&n,&k); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); } sort(a+1,a+n+1); int minn; minn=0x3f3f3f3f; int pos; int temp; for(int i=1;i<=n-k;i++) { temp=a[i+k]-a[i]; if(minn>temp){ minn=temp; pos=i; // printf("pos:%d temp:%d\n",pos,temp); mid=(a[pos+k]+a[pos])/2; //printf("mid:%d\n",mid); } } printf("%d\n",mid); } } return 0; }