码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 5857 Median (2016 多校训#10 1001)

时间:2016-08-18 23:01:55      阅读:140      评论:0      收藏:0      [点我收藏+]

标签:

题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5857

题意:给出一个已排好的序列,再给出两个范围(l1,r1,l2,r2),求由着两个子序列 组成的新序列的中位数,结果保留一位小数。

官方题解:

一个数组上的两个区间求中位数,可以通过分类讨论直接找到中位数,复杂度O(1).不过本题数据较小,优美的log(n)也可过.

分析:我用的是前者的方法。弄一个函数求新序列排第X在原序列的下标,如果长度是奇数,直接求排在第len/2+1位上的,偶数则中间两个的平均数。

找之前我先处理了一下,让l1<=l2。

中位数:将序列排好序后取中间的数,偶数序列则为中间二数和除2;

函数中主要讨论三种情况,一种是l2>=r1(1 2 3 4),这种最简单,直接找,第二种是有重叠部分(类似1 3 2 5),第三种(类似1 5 2 3)是第二串是第一串的子串,这种我发现和第二种是一样的,于是直接转化成第二种。(例如 1 5 2 3和1 3 2 5结果肯定是一样的);

(ps:由于复制后修改了第二种忘记改第三种了,于是WA了两次。)

代码:

技术分享
#include<cstdio>
#include<cmath>
#include<cstring>
#include<queue>
#include<stack>
#include<cstdlib>
#include<iomanip>
#include<string>
#include<vector>
#include<map>
#include<string>
#include<iostream>
#include<algorithm>
using namespace std;
#define INF 0x3f3f3f3f
typedef long long ll;
#define Max(a,b) (a>b)?a:b
#define lowbit(x) x&(-x)
int l1,l2,r1,r2,sum;
double a[100005];
double ans(int x)
{
    if(r1<=l2)
    {
        if(x<=r1-l1+1)
        {
            return a[l1+x-1];
        }
        else
        {
            return a[l2+x-1-r1+l1-1];
        }
    }
    else if(r1<=r2)
    {
        if(x<=l2-l1)
        {
            return a[l1+x-1];
        }
        else if(x>r1-l1+1+r1-l2+1)
        {
            return a[l2+x-r1+l1-1-1];
        }
        else
        {
            return a[l2+(x-l2+l1+1)/2-1];
        }
    }
    else
    {
        swap(r1,r2);
        if(x<=l2-l1)
        {
            return a[l1+x-1];
        }
        else if(x>r1-l1+1+r1-l2+1)
        {
            return a[l2+x-r1+l1-1-1];
        }
        else
        {
            return a[l2+(x-l2+l1+1)/2-1];
        }
    }
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=1; i<=n; i++)
        {
            scanf("%lf",&a[i]);
        }
        for(int i=0; i<m; i++)
        {
            scanf("%d%d%d%d",&l1,&r1,&l2,&r2);
            if(l1>l2)
            {
                swap(l1,l2);
                swap(r1,r2);
            }
            sum=r1-l1+1+r2-l2+1;
            if(sum%2)
            {
                printf("%.1f\n",ans(sum/2+1));
            }
            else
            {
                printf("%.1f\n",(ans(sum/2)+ans(sum/2+1))/2);
            }
        }
    }
}
View Code

 

HDU 5857 Median (2016 多校训#10 1001)

标签:

原文地址:http://www.cnblogs.com/wwdf/p/5785489.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!