POJ 3579 Median 查找中间值 二分
来源:互联网 发布:广州云计算培训 编辑:程序博客网 时间:2024/04/28 02:49
http://poj.org/problem?id=3579
这个题求的是一列数所有相互之间差值的序列的最中间的值是多少。看到数据可以看到用普通的n^2方法必定超时。
下面给出我写的两种方法。
第一种方法是用的是upper_bound,功能是在一段单调递增的序列中找到第一个大于目标元素的地址。用处是可以统计小于或等于value的元素有多少个(所以要减1)。该函数使用二分快速查找,时间性能log n。思路是对于某个确定的d,通过枚举第一个元素的下标来统计以这个元素为首的数对有多少个是满足a[j] - a[i] <= d 的,然后累加,从而计算出有多少个数对的差值是小于等于d的。记差值小于等于d的数对的个数关于d的函数为cnt(d),该函数单调递减,故使用左开右闭区间进行二分查找。
第二种方法使用的是lower_bound,功能是在一段单调递增的序列中找到第一个大于或等于目标元素的地址。用处是可以统计小于value的元素有多少个。使用左闭右开区间。
#include <cstdio>#include <iostream>#include <cstring>#include <algorithm>using namespace std;int a[100000+5];int n, m;bool ok(int d){ int cnt = 0; for(int i=0; i<n; i++){ cnt += (upper_bound(a+i, a+n, a[i]+d)-1 - (a+i)); } if(cnt >= m) return 1; else return 0;}int main(){ while(scanf("%d", &n) != EOF){ int c = n*(n-1)/2; if(c%2 == 0) m = c/2; else m = c/2 + 1; for(int i=0; i<n; i++) scanf("%d", &a[i]); sort(a, a+n); int lb = -1, ub = a[n-1] - a[0]; while(ub - lb > 1){ int mid = (lb+ub)>>1; if(ok(mid)) ub = mid; else lb = mid; } printf("%d\n", ub); } return 0;}
/*AC*/#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int maxn = 1e5+5;int a[maxn];int n, m;bool test(int val){ int cnt = 0; for(int i=0;i<n;i++){ cnt += (n-1)-(lower_bound(a+i+1,a+n,a[i]+val)-a)+1; } if(cnt > m) return 1; else return 0;}int main(){ while(scanf("%d",&n)!=EOF){m = n*(n-1)/4;for(int i=0;i<n;i++) scanf("%d",&a[i]);sort(a,a+n); int lb = 0, ub = a[n-1] - a[0] + 1; while(ub - lb > 1){ int mid = (lb+ub)>>1; if(test(mid)) lb = mid; else ub = mid; } printf("%d\n", lb); } return 0;}
0 0
- POJ 3579 Median 查找中间值 二分
- poj 3579 Median 二分查找与lower_bound
- POJ 3579(二分查找差值中间值)
- [POJ 3579] Median (二分答案+二分查找)
- Median - POJ 3579 二分
- POJ - 3579 Median 二分
- POJ 3579 Median(二分)
- POJ - 3579 Median (二分 + 查找第K大)
- POJ - 3579 Median(二分搜索,查找第K大的值)
- POJ 3579 - Median(二分搜索)
- POJ3579 Median(二分查找)
- POJ 3579 Median (查找第k大的值)
- POJ 3579 Median (二分搜索)
- POj 3579 Median(二分逼近)
- POJ 3579 Median(2次二分)
- 二分——POJ 3579 Median
- POJ 3679 Median 【二分】
- POJ 2010(二分最大化中间值)
- 2014年7月7日晚笔记
- jkkkkkkkkkkkkk
- 耻
- linux环境变量
- Netstat命令详解(windows下)
- POJ 3579 Median 查找中间值 二分
- linux下创建文件过多,导致inode用光
- 自定义 UITabbarController
- leedcode做题总结,题目Linked List Cycle I/II 13/10/28-30
- windows net 命令详解
- Codeforces 445A DZY Loves Chessboard(水题)
- 数据库的最简单实现
- C++类可以不显示声明构造函数,在创建类对象时编译器自动调用默认的构造函数
- POJ2828 Buy Tickets 【线段树】+【单点更新】+【逆序】