LOJ 1088 Points in Segments

来源:互联网 发布:君麻吕实力 知乎 编辑:程序博客网 时间:2024/06/05 17:22

题目大意:

        给定n个点(1 ≤ n ≤ 10^5),每个点都有一个整数值,范围是[0, 10^8],并且已经升序排列好了(每个点的值互不相同),现在给定q个段[a, b],其中a、b∈[0, 10^8],计算序列中每个给定段中点的个数,即p∈序列,且a ≤ p ≤ b的p的个数。

       现有多个测例(测例数会给出),每个测例中都给出n和q,以及n个元素的大小(升序排列输入的)以及q个段的左端值和右端值a和b,对于每个测例的每个段都给出位于段中的元素的个数。

题目链接

C语言实现lower_bound和upper_bound:

注释代码:

/*                                       * Problem ID : LOJ 1088 Points in Segments   * Author     : Lirx.t.Una                                       * Language   : C++                      * CPU  : 0.340                                       * Memory  : 1476                                      */ #include <stdio.h>//点集的最大长度#define MAXN        100000 int     a[MAXN]; intxbsrch( int lft, int rht, int x ) {//binary search in x//搜出大于等于x的第一个元素,即lower_bound     int     mid;     while ( lft < rht ) {           mid = ( lft + rht ) >> 1;         if ( a[mid] >= x )//一旦大于等于x就将区间置为左部            rht = mid;//此步保证结果位置一定最左        else//小于就mid左移//此步保证了结果位置的元素一定大于等于x            lft = mid + 1;    }     return lft;} intybsrch( int lft, int rht, int y ) {//binary search in y//搜出大于y的第一个元素,即upper_bound     int     mid;     while ( lft < rht ) {           mid = ( lft + rht ) >> 1;         if ( a[mid] > y )//一旦大于y就将区间置为右部            rht = mid;//此步保证结果位置一定最右        else//小于等于就mid右移//此步保证了结果一定大于y            lft = mid + 1;    }     return lft;} intmain() {     int     nscn, iscn;    int     n, k;//n个点k个段    int     x, y;//搜查的左右端点     int     p1, p2;//搜查结果的左右端点的数组下标     int     i;     scanf("%d", &nscn);    iscn = 0;     while ( nscn-- ) {           scanf("%d%d", &n, &k);        for ( i = 0; i < n; i++ )            scanf("%d", a + i);         printf("Case %d:\n", ++iscn);        while ( k-- ) {                   scanf("%d%d", &x, &y);            if ( a[n - 1] < x || a[0] > y ) {//如果搜查区间和点序列不重合//则无任何元素                puts("0");                continue;            }//特殊情况(y的srch不能正确处理这种特殊情况)            if ( x <= a[0] )//当左搜查元素小于等于序列最左端值                p1 = 0;//则左坐标就直接等于0(0号元素就是大于等于x的第一个元素了)            else                p1 = xbsrch( 0, n - 1, x );            if ( y >= a[n - 1] )//对于这种情况若使用ysrch,则其返回的就是//序列的最后一个元素,而不是最后一个元素的后一个位置                p2 = n;            else                p2 = ybsrch( p1, n - 1, y );//利用p1作为左端点,可以剪短搜索范围以节省时间            printf("%d\n", p2 - p1);        }    }    return 0;}

无注释代码:

#include <stdio.h> #define MAXN        100000 int     a[MAXN]; intxbsrch( int lft, int rht, int x ) {     int     mid;     while ( lft < rht ) {           mid = ( lft + rht ) >> 1;         if ( a[mid] >= x )            rht = mid;        else            lft = mid + 1;    }     return lft;} intybsrch( int lft, int rht, int y ) {     int     mid;     while ( lft < rht ) {           mid = ( lft + rht ) >> 1;         if ( a[mid] > y )            rht = mid;        else            lft = mid + 1;    }     return lft;}intmain() {    int     nscn, iscn;    int     n, k;    int     x, y;    int     p1, p2;    int     i;    scanf("%d", &nscn);    iscn = 0;    while ( nscn-- ) {        scanf("%d%d", &n, &k);        for ( i = 0; i < n; i++ )            scanf("%d", a + i);        printf("Case %d:\n", ++iscn);        while ( k-- ) {            scanf("%d%d", &x, &y);            if ( a[n - 1] < x || a[0] > y ) {                puts("0");                continue;            }            if ( x <= a[0] )                p1 = 0;            else                p1 = xbsrch( 0, n - 1, x );            if ( y >= a[n - 1] )                p2 = n;            else                p2 = ybsrch( p1, n - 1, y );            printf("%d\n", p2 - p1);        }    }    return 0;}

使用lower_bound和upper_bound二分搜索模板函数:

/*                                       * Problem ID : LOJ 1088 Points in Segments   * Author     : Lirx.t.Una                                       * Language   : C++                      * CPU      : 0.364                                       * Memory     : 2076                                      */ #include <algorithm>#include <iostream>#include <cstdio>#define MAXN        100001using namespace std;int     a[MAXN];intmain() {    int     nscn, iscn;    int     n, k;    int     x, y;    int     p1, p2;    int     i;    scanf("%d", &nscn);    iscn = 0;    while ( nscn-- ) {        scanf("%d%d", &n, &k);        for ( i = 0; i < n; i++ )            scanf("%d", a + i);        printf("Case %d:\n", ++iscn);        while ( k-- ) {            scanf("%d%d", &x, &y);            p1 = lower_bound(a, a + n, x) - a;            p2 = upper_bound(a + p1, a + n, y) - a;            printf("%d\n", p2 - p1);        }    }    return 0;}

单词解释:

dimensional:adj, 维度的,空间上的

n dimensional:adj, n维的

0 0
原创粉丝点击