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

题目链接: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);
            }
        }
    }
}

时间: 2024-12-29 09:57:17

HDU 5857 Median (2016 多校训#10 1001)的相关文章

(模拟)HDU - 5857 Median

原题链接:HDU5857 题意: 分析:先挂代码,分析等会写 代码: 1 #include <iostream> 2 #include <cstdio> 3 #include <cmath> 4 #include <algorithm> 5 6 using namespace std; 7 8 const int maxn=100010; 9 long long num[maxn]; 10 11 int main() { 12 int t; 13 scanf

HDU 5857 Median

因为原序列是排列好了的,那么只要看一下给出的两个区间相交的情况,然后分类讨论一下,O(1)输出. #pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<vector> #include<map> #i

HDU 4907 (杭电BC#3 1001)Task schedule(水)

题目地址:HDU 4907 水题...不多说..哈希后从后往前遍历一遍就行了. 代码如下: #include <iostream> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> #include <ctype.h> #include <queue> #include <map> #include<a

HDU 4975 (杭电多校 #10 1005题)A simple Gaussian elimination problem.(网络流之最大流)

题目地址:HDU 4975 对这题简直无语...本来以为这题要用什么更先进的方法,结果还是老方法,这么卡时间真的好吗....比赛的时候用了判环的方法,一直TLE..后来换了矩阵DP的方式,加了加剪枝就过了..无语了.. 代码如下: #include <cstdio> #include <cstring> #include <algorithm> #include <iostream> #include <cstdio> #include <

hdu 5881 Tea (2016 acm 青岛网络赛)

原题地址:http://acm.hdu.edu.cn/showproblem.php?pid=5881 Tea Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 451    Accepted Submission(s): 124 Problem Description Tea is good. Tea is life. Tea is e

2016年第10本:用系统来工作

从amazon上选书时,大数据系统推荐了此书.这本书适合一名小公司的老板来读,当自己整天忙乱到处救火时,肯定是公司的经营系统出了问题.道理很简单,却足以让人思考一番.该书作者曾艰难地经营了15年的电话应答服务公司,突然一天顿悟,明白了自己的系统出了问题,然后用一套简单实用的方法,一步步扭转他的事业和生活,每周工作时间减少了几十倍,收入却增加几十倍,看到这里都会让人有种打了鸡血的感觉,一路看下去,到底是什么牛X的办法?实际上就是发现系统,找到症结,建立规范的流程,不断执行和改进. 世界上到处都是系

Windows Server 2016 和Windows 10的中Hyper-V虚拟机生产检查点

Windows Server 2016慢慢的解开了它的面纱,感兴趣可以下载最新推出的Windows Server 2016 技术预览版4, 其中一部分虚拟机的功能在Windows 10的虚拟机中已经开放了,其中一个功能就是虚拟机生产检查点(Production Checkpoint). 对于检查点的概念,可能我们都是熟知的这个功能不是Hyper-V中早就提供了吗?注意,新推出的叫生产检查点,那么与之对应的功能就是标准检查点了(Standard Checkpoint).标准检查点和生产检查点?有神

hdu 5821 Ball(2016 Multi-University Training Contest 8——贪心+排序)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5821 Ball Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 515    Accepted Submission(s): 309 Problem Description ZZX has a sequence of boxes numbe

HDU 5698 瞬间移动 (2016&quot;百度之星&quot; - 初赛(Astar Round2B) 1003)

传送门 瞬间移动 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 140 Accepted Submission(s): 66 Problem Description 有一个无限大的矩形,初始时你在左上角(即第一行第一列),每次你都可以选择一个右下方格子,并瞬移过去(如从下图中的红色格子能直接瞬移到蓝色格子),求到第n行第m列的格子有几种方案