简单搜索入门(二):二分答案 HDU 5248

来源:互联网 发布:淘宝的皇家及行靠谱吗 编辑:程序博客网 时间:2024/05/17 02:42

二分练习的第二部分——二分答案的查找

1、HDU 5248 序列变换

Description

给定序列A={A1,A2,…,An}, 要求改变序列A中的某些元素,形成一个严格单调的序列B(严格单调的定义为:Bi< Bi+1, 1≤i< N)。
我们定义从序列A到序列B变换的代价为cost(A,B)=max(|Ai−Bi|)(1≤i≤N)。请求出满足条件的最小代价。注意,每个元素在变换前后都是整数。

Input

第一行为测试的组数T(1≤T≤10).
对于每一组:
第一行为序列A的长度N(1≤N≤105),第二行包含N个数,A1,A2,…,An.
序列A中的每个元素的值是正整数且不超过106。

Output

对于每一个测试样例,输出两行:

第一行输出:”Case #i:”。i代表第 i 组测试数据。

第二行输出一个正整数,代表满足条件的最小代价。

Sample Input

2
2
1 10
3
2 5 4

Sample Output

Case #1:
0
Case #2:
1

Solution

一开始阅读时以为是一道贪心的题目,就用贪心的策略敲了一遍,发现一直WA。后来看了一眼数据范围,就感觉像是二分,另一方面,注意到cost是最大值,只需要二分一下需要改变的最大值,然后判断当前的答案能否将原来的数列改变成一个严格单调的序列。

Code

#include <cstdio>#include <cstring>#include <cstdlib>#define MAXN 100003int a[MAXN],n;bool check(int s){    int st=a[1]-s;//第一个数字越小对后来越有利    for(int i=2;i<=n;i++)    {        int w=a[i]-s;//对当前的数字做最大尺度的改变        if(w<=st)        {            w=st+1;//可以构造的话就让当前的数字越小越好            if(abs(w-a[i])>s)//如果连最小的需求都无法满足则返回                return false;        }        st=w;    }    return true;}int main(){    int k;    while(scanf("%d",&k)!=EOF)    {        for(int j=1;j<=k;j++)        {            printf("Case #%d:\n",j);            scanf("%d",&n);            for(int i=1;i<=n;i++)                scanf("%d",&a[i]);            int l=0,r=1000001;//初始化最大值            while(l<r)            {                int mid=(l+r)>>1;                if(check(mid))//如果当前的值能够成功取右区间                    r=mid;                else                    l=mid+1;//如果不能则取左区间            }            printf("%d\n",r);//l与r都可以,        }    }    return 0;}

2、POJ 3579 Median

Time Limit: 1000MS
Memory Limit: 65536K
Total Submissions: 8524
Accepted: 2973

Description

Given N numbers, X1, X2, … , XN, let us calculate the difference of every pair of numbers: ∣Xi - Xj∣ (1 ≤ i < j ≤ N). We can get C(N,2) differences through this work, and now your task is to find the median of the differences as quickly as you can!
Note in this problem, the median is defined as the (m/2)-th smallest number if m,the amount of the differences, is even. For example, you have to find the third smallest one in the case of m = 6.

Input

The input consists of several test cases.
In each test case, N will be given in the first line. Then N numbers are given, representing X1, X2, … , XN, ( Xi ≤ 1,000,000,000 3 ≤ N ≤ 1,00,000 )

Output

For each test case, output the median in a separate line.

Sample Input

4
1 3 2 4
3
1 10 2

Sample Output

1
8

Source

POJ Founder Monthly Contest – 2008.04.13, Lei Tao

题意

对于给定的N个数字,将N个数任意两项的差值共M个全部算出,从小到大排序找出其中的中位数。

Solution

经典的二分查找答案的题目,通过两次的二分,第一次查找答案,第二次二分判断当前答案的正确性。
最大的差值不断二分答案每次判断一下当前差值t,用sum记录比a[i]大t的数字的个数,如果sum大于m/2,就取右区间,反之取左区间。
PS:二分查找在STL中有现成的模板
lower_bound(a,a+n,t)在数组中查找第一个大于(或等于)t的数字,返回指向大于(或等于)t的第一个迭代器—返回指针。
upper_bound(a,a+n,t)在数组中查找第一个大于t的数字,返回大于t的迭代器。

Code

#include <cstdio>#include <algorithm>using namespace std;int n;long a[100003],m,l,r,mid,res;bool che (int t){    int sum=0;    for(int i=1;i<=n;i++)        sum+=n-(lower_bound(a+1,a+n+1,a[i]+t)-a-1);    if(sum>m)        return true;    else        return false;}int main (){    while(scanf("%d",&n)!=EOF)      {        for(int i=1;i<=n;i++)            scanf("%ld",&a[i]);        sort(a+1,a+1+n);//排序保证二分的正确性        m=n*(n-1)/4;        l=0,r=a[n]-a[1];//初始化最大值为最大数字与最小数字的差值        while(l<=r)//二分答案        {            mid=(l+r)>>1;            if(che(mid))            {                res=mid;                l=mid+1;            }            else                r=mid-1;        }        printf("%d\n",res);    }    return 0;}
阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 棉短袖缩水了怎么办 公司忘记交社保怎么办 羊毛大衣粘毛怎么办 液态硅胶壳滑怎么办 穿内增高鞋脚疼怎么办 内增高太高怎么办 长钉球鞋铲不下怎么办 足球鞋买大了怎么办? 军靴穿着磨脚怎么办 军靴磨大脚趾怎么办 想开服装店没经验怎么办 我鼻子大怎么办啊 副局长不听局长的话怎么办 边防改制部局怎么办 毛中老师打人怎么办 老婆是个泼妇怎么办 一年级孩子学习不好怎么办 生活作息不规律怎么办 作息时间不规律怎么办 能醒不想起床怎么办 不想起床怎么办 神回复 孩子不起床上学怎么办 孕晚期起床困难怎么办 腰间盘疼痛起床困难怎么办 小学生做作业拖拉怎么办 被手机贷起诉怎么办 大人睡颠倒了怎么办 熬夜长斑了怎么办 ps遇到文件尾怎么办 pdf用ps打不开怎么办 ps安装不上怎么办 工作原因经常熬夜怎么办 熬夜皮肤暗黄怎么办 经常熬夜睡眠不好怎么办 经常熬夜皮肤不好怎么办 皮肤熬夜变暗黄怎么办 晚上上夜班白天睡不着怎么办 熬夜肾虚怎么办才能好 经常熬夜口气重怎么办 晚上睡不着白天起不来怎么办 晚上熬夜白天睡不着怎么办