STL之二分查找:hdu 5178 ( BestCoder Round #31 1001 )

STL包含四种不同的二分查找算法binary_search    lower_bound  upper_bound   equal_range.他们的作用域是已经排序好的的数组。

binary_search试图在已排序的[first, last)中寻找元素value。如果找到它会返回true,否则返回false,它不返回查找位置。

iterator
lower_bound( const key_type &key ): 返回一个迭代器,指向键值>=
key
的第一个元素。

iterator
upper_bound( const key_type &key ):返回一个迭代器,指向键值> key的第一个元素。

                                                             hdu 5178 pairs

Problem Description

John has n points
on the X axis, and their coordinates are (x[i],0),(i=0,1,2,…,n?1).
He wants to know how many pairs<a,b> that |x[b]?x[a]|≤k.(a<b)

Input

The first line contains a single integer T (about
5), indicating the number of cases.

Each test case begins with two integers n,k(1≤n≤100000,1≤k≤109).

Next n lines
contain an integer x[i](?109≤x[i]≤109),
means the X coordinates.

Output

For each case, output an integer means how many pairs<a,b> that |x[b]?x[a]|≤k.

Sample Input

2
5 5
-100
0
100
101
102
5 300
-100
0
100
101
102

Sample Output

3
10

Source

BestCoder Round #31

参考代码一(使用二分查找函数upper_bound)

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <map>
#include <vector>
#include <queue>
#include <cstring>
#include <cmath>
#include <climits>
#define eps 1e-10
using namespace std;
typedef long long ll;
const int INF=INT_MAX;
const int maxn = 1e5+10;
int n,k,a[maxn];
int main()
{
 //  freopen("input.txt","r",stdin);
   int T;cin>>T;
   while(T--){
    cin>>n>>k;
    for(int i=0;i<n;i++) scanf("%d",a+i);
    sort(a,a+n);
    ll ans=0;
    for(int i=0;i<n;i++){
     ans+=upper_bound(a,a+n,a[i]+k)-a-1-i;//upper_bound返回值-a得到<=a[i]+k的元素个数,再-1是为了矫正初始位置从0开始,最后减去i得到的是与i的pair个数
    }
    printf("%lld\n",ans);
   }
   return 0;
}

参考代码二(手写二分查找函数)

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <map>
#include <vector>
#include <queue>
#include <cstring>
#include <cmath>
#include <climits>
#define eps 1e-10
using namespace std;
typedef long long ll;
const int INF=INT_MAX;
const int maxn = 1e5+10;
int n,k,a[maxn];
ll ans;
int binary_search(int num,int pos){
 int low=pos+1,high=n-1,mid,res=0;
 while(low<=high){
    mid=(low+high)>>1;
    if(a[mid]-num>k) high=mid-1;
    else{
    res=mid-pos;//直接得到pair个数,否则还要判断有没有结果再处理
    low=mid+1;
    }
 }
  return res;//没有则返回初始值0
}
int main()
{
  // freopen("input.txt","r",stdin);
   int T;cin>>T;
   while(T--){
    scanf("%d%d",&n,&k);
    for(int i=0;i<n;i++) scanf("%d",a+i);
    sort(a,a+n);
    ans=0;
    for(int i=0;i<n;i++){
      ans+=binary_search(a[i],i);//累加过程
    }
    printf("%lld\n",ans);
   }
   return 0;
}
时间: 2024-08-09 01:08:05

STL之二分查找:hdu 5178 ( BestCoder Round #31 1001 )的相关文章

HDU 5280 BestCoder Round #47 1001:Senior&#39;s Array

Senior's Array Accepts: 199 Submissions: 944 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) 问题描述 某天学姐姐得到了一个数组A,在这个数组的所有非空区间中,她找出了一个区间和最大的,并把这个区间和定义为这个数组的美丽值. 但是她觉得这个数组不够美,于是决定修理一下这个数组. 学姐姐将会进行一次操作,把原数组中的某个数修改为P(必须修改)

hdu 4857/BestCoder Round#1 1001(拓扑排序+逆向建图)

此题需细致分析题目,否则题意easy理解错误.应注意以下这样的情况 本题意思尽可能让最小的排的靠前.然后次小的尽量靠前.依次下去 如 input: 1 3 1 3 1 output: 3 1 2 解析:我们应让1尽可能的排在前面.然后尽可能的让2排的靠前.. .所以 2 3 1的结果是错误的 思路:拓扑排序(逆向建图+队列)//为解决上述列子.假设我们正向建图.每次选择入度为零最小的编号输出则无法满足上述案例. 假设我们尝试逆向建图,每次选择入度为零的最大编号输出则刚刚是正确结果的逆序(省赛并查

hdu 4857/BestCoder Round#1 1001(逆向建图)

此题需仔细分析题目,否则题意容易理解错误,应注意下面这种情况 本题意思尽可能让最小的排的靠前,然后次小的尽量靠前,依次下去 如 input: 1 3 1 3 1 output: 3 1 2 解析:我们应让1尽可能的排在前面,然后尽可能的让2排的靠前...所以 2 3 1的结果是错误的 思路:拓扑排序(逆向建图+队列)//为解决上述列子,如果我们正向建图,每次选择入度为零最小的编号输出则无法满足上述案例: 如果我们尝试逆向建图,每次选择入度为零的最大编号输出则刚刚是正确结果的逆序(省赛并查集的逆用

HDU BestCoder Round #1 1001 逃生 【拓扑排序】

逃生 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 0    Accepted Submission(s): 0 Problem Description 糟糕的事情发生啦,现在大家都忙着逃命.但是逃命的通道很窄,大家只能排成一行. 现在有n个人,从1标号到n.同时有一些奇怪的约束条件,每个都形如:a必须在b之前. 同时,社会是不平等的

STL之二分查找 (Binary search in STL)

STL之二分查找 (Binary search in STL) Section I正确区分不同的查找算法count,find,binary_search,lower_bound,upper_bound,equal_range 本文是对Effective STL第45条的一个总结,阐述了各种查找算法的异同以及使用他们的时机. 首先可供查找的算法大致有count,find,binary_search,lower_bound,upper_bound,equal_range.带有判别式的如count_i

BestCoder Round #3 1001 &amp;&amp; HDU 4907 Task schedule (预处理)

题目链接:HDU 4907 Task schedule 中文题. 思路:将工作表存在vis的组数中.预处理一遍.具体看代码 AC代码: #include<stdio.h> #include<string.h> bool vis[200100]; int tak[200100]; int main() { int j,i,ti; int n,m,t,num; while(scanf("%d",&t)!=EOF) { while(t--) { memset(

【C++】【STL】二分查找函数

binary_search 这个函数的返回值是布尔型,也就是最简单的找到了就为真,没找到就是假. 传入参数有三个,数据集合的左端点,数据集合的右端点,查找的值. 注意这些左端点右端点是要求左开右闭原则的,就是和数学上的左开右闭区间[a, b)一样,右端点是个不会被查阅的值. 一般来说写法类似: bool flag = false; int data[n] = {...};///数据 sort(data, data + n); flag = binary_search(data, data + n

HDU 5281 BestCoder Round #47 1002:Senior&#39;s Gun

Senior's Gun Accepts: 235 Submissions: 977 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) 问题描述 学姐姐是一个酷酷的枪手. 她常常会随身携带n把枪,每把枪有一个攻击力a[i]. 有一天她遇到了m只怪兽,每只怪兽有一个防御力b[j].现在她决定用手中的枪消灭这些怪兽. 学姐姐可以用第i把枪消灭第j只怪兽当且仅当b[j]≤a[i],同时她会获

BestCoder Round #1 1001 &amp;&amp; 1002 hdu 4857 4858

hdu 4857 逃生 第一题是拓扑排序,不是按照字典序最小输出,而是要使较小的数排在最前面..赛后弄了好久,才比较明白,我一直以为 反向建图,i从1到n,开始深搜dfs( i ),对i点的边,由小到大继续搜一下,同时标记搜过的数,搜过之后就不再搜,搜到底之后ans[cnt++] = u;这样顺序输出就是答案,后来经过超哥指点,才明白深搜贪心是错的.只有 反向建图,用优先队列把较大的数尽量排在前面,然后反序输出才是正解.. 1 #include<iostream> 2 #include<