poj3579,二分找答案,再二分查找
2015-10-31 18:52
260 查看
题意:
给一堆数,先求出所有两个数的差值;
输出这些数的中位数;
理解:
直接枚举这些数肯定会超时,因为有C(n, 2)个,这是非常大的;
我开始是直接枚举我们要求的第中位数个的值,但这个数也是非常大的;
然后看了下别人的思路,发现我依然天真。。。
是这样的,先二分找答案,就是在一个范围内二分枚举答案;
判断这个答案是否行得通;
怎么判断呢?
二分查找在这个值的基础上有几个大于它的,即为不在该范围内的数;
我也不懂怎么要这样去找,但它就是对的。。。。
可能是因为这个值恰好比前面的那些差值大于等于,而这个数就是答案。
代码如下:
代码最能说明为什么,当然也需要模拟。。
给一堆数,先求出所有两个数的差值;
输出这些数的中位数;
理解:
直接枚举这些数肯定会超时,因为有C(n, 2)个,这是非常大的;
我开始是直接枚举我们要求的第中位数个的值,但这个数也是非常大的;
然后看了下别人的思路,发现我依然天真。。。
是这样的,先二分找答案,就是在一个范围内二分枚举答案;
判断这个答案是否行得通;
怎么判断呢?
二分查找在这个值的基础上有几个大于它的,即为不在该范围内的数;
我也不懂怎么要这样去找,但它就是对的。。。。
可能是因为这个值恰好比前面的那些差值大于等于,而这个数就是答案。
代码如下:
代码最能说明为什么,当然也需要模拟。。
#include <cstdio> #include <cstring> #include <algorithm> #include <iostream> #include <queue> #include <string> #include <set> #include <cmath> using namespace std; #define maxn 100100 #define x first #define y second #define ll long long #define P pair<ll, ll> #define INF 1e9 int a[maxn]; bool solve(int t, int m, int n) { int count = 0; for (int i = 0; i < n; ++i) { count += n - (lower_bound(a, a + n, a[i] + t) - a); //二分找位置,以确定答案是否可行 } if (count <= m) { return false; } else return true; } int main() { int n; while(~scanf("%d", &n)) { for (int i = 0; i < n; ++i) { scanf("%d", &a[i]); } sort(a, a + n); ll m = n * (n - 1) / 4; int lb = 0, rb = a[n - 1]; //答案一定存在这两个之间 while(rb - lb > 1) //二分答案 { int mid = (lb + rb) / 2; if (solve(mid, m, n)) { lb = mid; } else { rb = mid; } } printf("%d\n", lb); } return 0; }
相关文章推荐
- C++二分查找在搜索引擎多文档求交的应用分析
- C#二分查找算法实例分析
- 在MySQL中实现二分查找的详细教程
- Java实现二分查找算法实例分析
- Python二分查找详解
- 简介二分查找算法与相关的Python实现示例
- 漫谈递归:二分查找算法的递归实现
- 二分查找
- 折半查找法
- "二分查找(Binary Search)"与"斐波那契查找(Fibonacci Search)"
- 初学ACM - 组合数学基础题目PKU 1833
- 二分查找
- C#版二分查找(代碼)
- POJ ACM 1001
- POJ ACM 1002
- POJ 2635 The Embarrassed Cryptographe
- POJ 3292 Semi-prime H-numbers
- POJ 2773 HAPPY 2006
- POJ 3090 Visible Lattice Points
- POJ-2409-Let it Bead&&NYOJ-280-LK的项链