C. Median
time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

A median in an array with the length of n is an element which occupies position number  after we sort the elements in the non-decreasing order (the array elements are numbered starting with 1). A median of an array (2, 6, 1, 2, 3) is the number 2, and a median of array (0, 96, 17, 23) — the number 17.

We define an expression  as the integer part of dividing number a by number b.

One day Vasya showed Petya an array consisting of n integers and suggested finding the array's median. Petya didn't even look at the array and said that it equals x. Petya is a very honest boy, so he decided to add several numbers to the given array so that the median of the resulting array would be equal to x.

Petya can add any integers from 1 to 105 to the array, including the same numbers. Of course, he can add nothing to the array. If a number is added multiple times, then we should consider it the number of times it occurs. It is not allowed to delete of change initial numbers of the array.

While Petya is busy distracting Vasya, your task is to find the minimum number of elements he will need.

Input

The first input line contains two space-separated integers n and x (1 ≤ n ≤ 500, 1 ≤ x ≤ 105) — the initial array's length and the required median's value. The second line contains n space-separated numbers — the initial array. The elements of the array are integers from 1 to 105. The array elements are not necessarily different.

Output

Print the only integer — the minimum number of elements Petya needs to add to the array so that its median equals x.

题目大意:给你一个数n 和一个数k,然后给你一个由n个数组成的数列,先按非递减序排好,然后让你判断这个数列的第 (n + 1) / 2  项是不是k(数列的下标从1开始),如果不是,你要往这个数列中插入m个数使插入后的数列的第(n + m + 1) /  2 项是k , 输出m的最小值。

解题思路:先判断数k是否在原数列中,没有的话就把数k加入数列,然后原始数列排序,接着找出数k在数列中第一次 first 和最后一次出现的位置second,同时算出 t  =(n + 1)/ 2  ,如果 t >= first && t <= second , 就直接输出结果;如果  t  <  first ,则需要在数k的后面添加    大于或等于 k    的数 ;如果 t  > second , 则需要在数k的前面     小于或等于 k      的数。

Ps: 此题用暴力法可能会TLE, 我用的是二分法,只是其中有许多细节需要注意。具体请看代码:

#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
using namespace std ;
const int MAXN = 1e5 + 5 ;
int vis[MAXN] ;
int s[MAXN] ;
bool cmp(int a , int b)
{
return a < b ;
}
int main()
{
int n , k ;
while (scanf("%d%d" , &n , &k) != EOF)
{
int i ;
int ans = 0 ;
memset(vis , 0 , sizeof(vis)) ;
for(i = 1 ; i <= n ; i ++)
{
scanf("%d" , &s[i]) ;
vis[s[i]] ++ ;
}
if(vis[k] == 0) // 如果数列中没有k,则加入k
{
vis[k] ++ ;
n ++ ;
s[n] = k ;
ans ++ ;
}
sort(s + 1, s + n + 1, cmp) ; // 因为数列的下标是从1 开始的,
//所以要把 1 ~ n 项排序
int t = (n + 1) >> 1 ;
int first = -1 ;
int second = -1 ;
int j ;
for(j = 1 ; j <= n ; j ++) // 记录 k 第一次出现的位置和最后一次出现的位置
{
if(k == s[j])
{
if(first == -1)
first = j ;
second = j ;
}
}
if(t >= first && t <= second)
{
printf("%d\n" , ans) ;
}
// 以下是二分过程,是此程序的精华,请仔细理解
else if( t < first)
{
int r = n , l = 1 , mid ;
while(r > l + 1) // 注意跳出条件
{
mid = (r + l) >> 1 ;
int tmp = (mid + n + 1) >> 1 ;
if(first < tmp )
{
r = mid - 1 ;
}
else if(first > tmp)
{
l = mid ;
}
else // 注意相等的情况也要单独判断
{
r = mid ;
}
}
if(r == l + 1) // 此处也是必不可少的 !!
{
if((l + n + 1) >> 1 == first)
{
ans += l ;
}
else
ans += r ;
}
else
ans += r ;
printf("%d\n" , ans) ;
}
// 以下过程道理同上
else
{
int r = n , l = 1 , mid ;
while (r > l + 1)
{
mid = (r + l) >> 1 ;
int tmp = (n + mid + 1) >> 1 ;
if(second + mid < tmp)
{
l = mid + 1;
}
else if(second + mid == tmp)
{
r = mid ;
}
else
{
r = mid - 1 ;
}
}
if(r == l + 1)
{
if((l + n + 1) >> 1 == second + l)
{
ans += l ;
}
else
ans += r ;
}
else
ans += r ;
printf("%d" , ans) ;
}
}
return 0 ;
}

codeforces 166C Median - from lanshui_Yang的更多相关文章

  1. ACM学习历程—CodeForces 590A Median Smoothing(分类讨论 && 数学)

    题目链接:http://codeforces.com/problemset/problem/590/A 题目大意是给一个串,头和尾每次变换保持不变. 中间的a[i]变成a[i-1],a[i],a[i+ ...

  2. CodeForces 590A Median Smoothing

    构造题. 答案可以o(n)构造出来.首先要发现规律.只有01交替的串才可能变化,变化规律如下: 1开头,长度为偶数(0结尾):变(len-2)/2次 变完后 前半1 后半01开头,长度为奇数(1结尾) ...

  3. OUC_Summer Training_ DIV2_#9 719

    其实自己只会做很简单的题,有时都不想写解题报告,觉得不值得一写,但是又想到今后也许就不会做ACM了,能留下来的东西只有解题报告了,所以要好好写,很渣的题也要写,是今后的纪念. B - B Time L ...

  4. Codeforces Round #327 (Div. 2) C. Median Smoothing 找规律

    C. Median Smoothing Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/591/p ...

  5. 【22.70%】【codeforces 591C】 Median Smoothing

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  6. Codeforces Round #327 (Div. 2) B. Rebranding C. Median Smoothing

    B. Rebranding The name of one small but proud corporation consists of n lowercase English letters. T ...

  7. codeforces 590A A. Median Smoothing(思维)

    题目链接: A. Median Smoothing time limit per test 2 seconds memory limit per test 256 megabytes input st ...

  8. Median String CodeForces - 1144E

    You are given two strings ss and tt, both consisting of exactly kk lowercase Latin letters, ss is le ...

  9. Codeforces 1005 E2 - Median on Segments (General Case Edition)

    E2 - Median on Segments (General Case Edition) 思路: 首先我们计算出solve(m):中位数大于等于m的方案数,那么最后答案就是solve(m) - s ...

随机推荐

  1. 为MyEclipse加入自己定义凝视

    非常多时候我们默认的MyEclipse的类凝视是这种,例如以下图 能够通过改动MyEclipse的凝视规则来改变,不但能够改动类的.还能够改动字段.方法等凝视规则,操作方法例如以下 1.针对方法的凝视 ...

  2. MySQL复制协议

    http://hamilton.duapp.com/detail?articleId=27

  3. p标签里面不要放div标签(块元素)

    最好不要在p标签里面嵌套块级元素(如div Ul): <p>我来测试下<div>块元素</div>放在p标签的情况</p> <p>我来测试下 ...

  4. DataTable复制自身行

    在我们工作的过程中有可能要使用DataTable产生一些重复数据(在不重复读取数据库的情况下) 无废话,直接上代码 DataTable复制自身一行(目的产生重复数据),已测试通过可直接复制 /// & ...

  5. C/C++中的const int*和int * const

    代码: #include <iostream> using namespace std; int main(){ const int *p; ; p = &a; a = ; cou ...

  6. log4net 使用步骤

    1.安装log4net 官网首页:http://logging.apache.org/log4net/ 下载地址:http://logging.apache.org/log4net/download_ ...

  7. C/C++ 中##(两个井号)和#(一个井号)用法

    ##(两个井号)和#(一个井号)都是什么意思 连接符 ##(两个井号) 不知道什么符 #(一个井号) ## 连接符号由两个井号组成,其功能是在带参数的宏定义中将两个子串(token)联接起来,从而形成 ...

  8. DOM 节点实例操作

    涉及知识点包括节点的所有知识 目的: 自动为文档创建一个目录表 自动创建目录

  9. C# txt文件读写

    //读取文件内容 (1).使用FileStream类进行文件的读取,并将它转换成char数组,然后输出. ]; ]; public void Read() { try { FileStream fil ...

  10. 【5】python核心编程 第八章-条件和循环

    1.=== range() 的完整语法=== Python 提供了两种不同的方法来调用 range() . 完整语法要求提供两个或三个整数参数: range(start, end, step =1) ...