poj-3579 Median
2015-12-29 01:48
323 查看
题意给你n个数。两两相差的绝对值有c(n,2)个,有这c(n,2)个数的中位数
完全没法做啊有木有。。。完全没思路。。。
然后看了题解。。。
主题思路。。
先对xi sort一下。然后进行第一次二分。
参考博客点击打开链接
c(x) 表示以x为相隔距离的个数能否大于等于c(n,2)/2个。能满足。不能就不满足。。。
好这里我有点卡了。大于c(n,2)/2怎么办?不是等于c(n,2)/2吗。。。好吧我蠢。
会不会一直大于c(n,2)/2个的距离。。。不会。。。。。
先写思路。。。
额,用low_bound和upper_bound两种方法写吧。。
使用low_bound的函数理解。。。
代码:
细节理解。。。。
1.使用low_bound是为什么从a+i+1开始?
low_bound返回的是大于等于a[i]+val的第一个元素的地址。当val等于0时。返回的自身值的地址。这是不可取的。因为间隔的距离是不能与自身比较的。
2.(n-1)-(lower_bound(a+i+1,a+n,a[i]+val)-a)+1中为什么是n-1并且要+1?
(lower_bound(a+i+1,a+n,a[i]+val)-a)返回的是a数组的下标。下标的顶值是n-1,
加1,举个例子
0 1 2 3 4 5
2 3 5 8 9 10
假如a[i]+val=a[0]+val=2+1=3,那么返回的是1.n-5为5.5-1=4.而实际是4个元素,所以要加1.
3.right=*max_element(x,x+n)-*min_element(x,x+n)+1为什么要加1?
在c的判断函数中,if(sum > goal)是满足的,此时真值为left,这是为了避免极端情况当答案是一直向右二分,最后答案是right但是只能输出right-1,所以应该加1.
4.对中位数的表达中,为什么直接使用goal = n*(n-1)/4,然后在c的判断中使用的是sum>goal?不应该分类讨论n*(n-1)/2的奇偶然后对应是否加1,判断条件中位sum>=goal?
因为区间是前闭后开区间。在实现的过程中right=*max_element(x,x+n)-*min_element(x,x+n)+1。区间长度加大了1.原来偶数成为奇数,奇数成为偶数,所以若n*(n-1)/2为
偶数,n*(n-1)/2的中位数是不满足加1后的中位数。所以应该加1。若n*(n-1)/2为奇数,那么加1除以2后的值是满足的。而原式中n*(n-1)/2相对以前是少1的。所以应该加1.
综合,是sum>goal。。。
对于upper_bound。输出是rb,这是因为c的判断是可以统计小于或等于value的元素有多少个(所以要减1)。left是因为避免极端情况用上了-1.。。
但是为什么使用确定的中位数位置。这点我没理解。感觉有个数学推导。。。。所以我就掌握一种方法吧。哎╮(╯▽╰)╭。
另外一种方法不能理解。就背下来吧。。
还有5个题二分搜索这章就完了。。。。明天做完加上总结吧
codeforces的总结和区间dp的放在星期三。。。。。。 不慌不忙,不骄不躁。
完全没法做啊有木有。。。完全没思路。。。
然后看了题解。。。
主题思路。。
先对xi sort一下。然后进行第一次二分。
参考博客点击打开链接
c(x) 表示以x为相隔距离的个数能否大于等于c(n,2)/2个。能满足。不能就不满足。。。
好这里我有点卡了。大于c(n,2)/2怎么办?不是等于c(n,2)/2吗。。。好吧我蠢。
会不会一直大于c(n,2)/2个的距离。。。不会。。。。。
先写思路。。。
额,用low_bound和upper_bound两种方法写吧。。
使用low_bound的函数理解。。。
代码:
#include <iostream> #include <map> #include <algorithm> #include <cstdio> #include <cstring> #include <cstdlib> #include <vector> #include <queue> #include <stack> #include <functional> #include <set> #include<sstream> #include <cmath> using namespace std; #define pb push_back #define PB pop_back #define bk back() #define fs first #define se second #define INF 1e18+10 #define sq(x) (x)*(x) #define eps (1e-10) #define clr(x) memset((x),0,sizeof (x)) #define cp(a,b) memcpy((a),(b),sizeof (b)) typedef long long ll; typedef unsigned long long ull; typedef pair<int,int> P; const int maxn=100100; int x[maxn]; int n; ll goal; bool c(int mid) { ll sum=0; for(int i=0;i<n;i++) sum+=(n-1)-(lower_bound(x+i+1,x+n,x[i]+mid)-x)+1; //* return sum>goal;//* } int main() { while(~scanf("%d",&n)) { for(int i=0;i<n;i++) scanf("%d",&x[i]); sort(x,x+n); goal=(n-1)*n>>2;//* int left=0;//* int right=*max_element(x,x+n)-*min_element(x,x+n)+1;//* int mid=0; while(right-left>1) { mid=(right+left)>>1; if(c(mid)) left=mid; else right=mid; } printf("%d\n",left); } return 0; }
细节理解。。。。
1.使用low_bound是为什么从a+i+1开始?
low_bound返回的是大于等于a[i]+val的第一个元素的地址。当val等于0时。返回的自身值的地址。这是不可取的。因为间隔的距离是不能与自身比较的。
2.(n-1)-(lower_bound(a+i+1,a+n,a[i]+val)-a)+1中为什么是n-1并且要+1?
(lower_bound(a+i+1,a+n,a[i]+val)-a)返回的是a数组的下标。下标的顶值是n-1,
加1,举个例子
0 1 2 3 4 5
2 3 5 8 9 10
假如a[i]+val=a[0]+val=2+1=3,那么返回的是1.n-5为5.5-1=4.而实际是4个元素,所以要加1.
3.right=*max_element(x,x+n)-*min_element(x,x+n)+1为什么要加1?
在c的判断函数中,if(sum > goal)是满足的,此时真值为left,这是为了避免极端情况当答案是一直向右二分,最后答案是right但是只能输出right-1,所以应该加1.
4.对中位数的表达中,为什么直接使用goal = n*(n-1)/4,然后在c的判断中使用的是sum>goal?不应该分类讨论n*(n-1)/2的奇偶然后对应是否加1,判断条件中位sum>=goal?
因为区间是前闭后开区间。在实现的过程中right=*max_element(x,x+n)-*min_element(x,x+n)+1。区间长度加大了1.原来偶数成为奇数,奇数成为偶数,所以若n*(n-1)/2为
偶数,n*(n-1)/2的中位数是不满足加1后的中位数。所以应该加1。若n*(n-1)/2为奇数,那么加1除以2后的值是满足的。而原式中n*(n-1)/2相对以前是少1的。所以应该加1.
综合,是sum>goal。。。
对于upper_bound。输出是rb,这是因为c的判断是可以统计小于或等于value的元素有多少个(所以要减1)。left是因为避免极端情况用上了-1.。。
但是为什么使用确定的中位数位置。这点我没理解。感觉有个数学推导。。。。所以我就掌握一种方法吧。哎╮(╯▽╰)╭。
另外一种方法不能理解。就背下来吧。。
还有5个题二分搜索这章就完了。。。。明天做完加上总结吧
codeforces的总结和区间dp的放在星期三。。。。。。 不慌不忙,不骄不躁。
相关文章推荐
- JSP实现HTML网页对Mysql数据库的数据修改
- 生产者消费者问题【线程中ConcurrentLinkedQueue】
- 线性表链式存储结构实现--静态链表
- [LeetCode] 45. Jump Game II 解题思路
- 线性表链式存储结构实现 --单链表
- Burndown chart
- Git下使用版本回退粗暴解决冲突问题
- linux下网卡配置管理工具ifconfig小结
- php生成网页桌面快捷方式
- JSP实现HTML网页中分页查询Mysql数据库数据
- ubuntu和win7引导修复
- ThinkPHP+JQuery实现ajax无刷新登录验证(详解+相关问题)
- PL/SQL 64位发布啦!!!
- No resource found that matches the given name 'android:TextAppearance.Material.Widget.Button.Inverse
- AndroidManifest.xml file missing!
- JSP实现HTML网页管理Mysql数据库
- Android 图片选择和裁剪 之 PictureTool
- CSS2.1SPEC:视觉格式化模型之width属性详解(上)
- 浅谈Python时间模块
- codeforces 609E. Minimum spanning tree for each edge 树链剖分