POJ3579 二分
来源:互联网 发布:linux根目录介绍 编辑:程序博客网 时间:2024/06/06 17:18
这题也是二分,但有很多特殊的地方:
题意是输入一串数,这些数之间的差排成一列,找出其中的中位数第一次二分枚举猜测中位数为mid,比较a[i]+mid与后面的数,与m比较确定区间,第二次二分是在比较的过程中,如果用两个迭代还是N^2,所以用二分求上界,总数减去返回的下标值就是后面大于或等于a[i]+mid的数量。
这题有个奇怪的地方,说是第m/2个最小值为中位数但如1,2,10的差是1,8,9,中位数是8,但m=1。
而且这题step=mid必须放到sum>m后,也就是说中位数时sum只大于m,不包括等于m的情况,可以写几个数据验证一下,题目给的第一组数据就可以看出来,以后做这种题这些地方最好还是验证一下
代码如下:
#include<stdio.h>#include<stdlib.h>#include<string.h>#define maxn 100000+100int a[maxn], n,m;int cmp(const void*a, const void*b){ return *(int*)a - *(int*)b;}int lower_bound(int left, int right, int v)//二分求上界{ int m; while (left < right) { m = (left + right) / 2; if (a[m] >= v) right = m; else left = m + 1; } return left;}bool test(int mid){ int i,sum=0; for (i = 0; i < n; i++) { sum += n - lower_bound(i,n,a[i]+mid);//再次二分减少时间 } if (sum > m) //大于说明mid开小了 return true; else return false;}int main(){ while (scanf("%d", &n) != EOF) { int left = 0, right = 0, mid,step; int i; for (i = 0; i < n; i++) scanf("%d", &a[i]); qsort(a, n, sizeof(a[0]), cmp); m = n*(n - 1) / 4; right = a[n - 1] - a[0]; while (left <= right) { mid = (left + right) / 2; if (test(mid)) { step = mid; //注意这步一定要放这里,可以找几个例子推一下 left = mid + 1; } else { right = mid - 1; } } printf("%d\n", step); } return 0;}
0 0
- poj3579 二分
- POJ3579 二分
- POJ3579 Median(二分查找)
- poj3579 Median 二分
- POJ3579:Median(二分)
- POJ3579--Median(二分)
- POJ3579 二分判定+二分查找
- 二分搜索(两次)-poj3579
- POJ3579 Median —— 二分
- poj3579,二分找答案,再二分查找
- poj3579
- poj3579
- POJ3579
- POJ3579
- poj3579
- POJ3579 Median(二分答案 + O(N)判定)
- POJ3579 Median(二分答案 + O(N)判定)
- poj3579 双重二分,有意思的一道题,注意二分边界
- 使用注解描述的Servlet程序开发
- 一起talk C栗子吧(第七十三回:C语言实例--DIY pwd命令)
- 旋转数组的最小数字
- 单例模式
- android学习笔记——GridView控件(九宫格布局)
- POJ3579 二分
- STM32学习笔记(4):SysTick
- poj 1860-Currency Exchange(Bellman_Ford算法)
- [笔记] 大型网站技术架构——核心原理与案例分析 [一]
- 斐波那契数列
- android学习笔记——ImageSwitcher控件(图片切换器)
- 关于”点九”
- android开发步步为营之87:从sdcard或者data文件夹下读写数据
- Round #6 (Div. 2 Only) (E )(RMQ+尺取法)