NO.4 题析-3.24初测 第一题 P1168中位数

题目描述

给定一个长度为 NN 的非负整数序列 AA,对于前奇数项求中位数。

输入格式

第一行一个正整数 NN。

第二行 NN 个正整数 A_{1\dots N}A1…N​。

输出格式

共(n+1)/2(向下取整) 行,第i行为A1....2i-1的中位数。

说明/提示

对于 20% 的数据,N ≤100;

对于 40% 的数据,N ≤3000;

对于 100% 的数据,1 ≤N≤100000,0≤Ai​≤10的九次方

标签:线段树 二分 堆 树状数组(挂的好多啊)

难度:普及/提高-

题目传送门:中位数 - 洛谷

题析

题目很简短,就是给你一个序列,每奇数个数求一次中位数

这个时候我相信大多数人第一想法都是简简单单开开心心每次搞进来两个数sort排序输出中间

这实现起来相当简单

40分代码

#include<bits/stdc++.h>
using namespace std;
long long a[200002],b[200002];
long long n;
int main()
{
    ios::sync_with_stdio(0);
    cin>>n;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    for(int i=1;i<=n;i+=2)
	{
        sort(a+1,a+i+1);
        cout<<a[(i+1)/2]<< endl;
    }
    return 0;
}

不放评测记录也都清楚,这种算法是n² log n级别的,肯定超时一大片

那么怎么优化呢?

插入排序固然是有用的,但是经过神犇老师的代码测试,仍然是40分(还不如不写呢)

尽管插入排序把时复降到了n log n的级别,仍然超时一大片

那么,我们就应该寻找时间复杂度为log n的方式

不难想到二分,可是仍然难以实现

这个时候我们就要用到一个神奇的数据结构

它就是vector!(俗称可变数组)

介绍一下它的基本操作(引用洛谷大佬题解、深入浅出)

vc.push_back()在vectorvector末尾插入一个数据

vc.insert()vc.insert()在vectervecter中插入一个元素

vc.erase()vc.erase()在vectorvector中删除一个元素

很棒是不是?完美符合我们的需求

再用upper_bound来二分小于等于该数的数的指针,使得每次插入完都是已经排好序

每次插入后,输出(size()−1)/2即可

AC代码

#include <bits/stdc++.h>
using namespace std;
int n; vector<int>a;//命名vector数组
int main(){
 scanf("%d", &n);
 for(int i=1, x;i<=n;i++){
 scanf("%d", &x);
 a.insert(upper_bound(a.begin(),a.end(),x),x);//二分指针所在位置
 if(i%2==1)
 printf("%d\n",a[(i-1)/2]);
 }
 return 0;
}

完awa

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值