训练赛

思路:

欲维护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;
}

 

posted @ 2019-08-16 11:47  Orangeko  阅读(210)  评论(2编辑  收藏  举报