第三集 我说,那是我哥_模糊二分搜索

第三集 我说,那是我哥

TimeLimit:2000ms  MemoryLimit:128000KB
64-bit integer IO format:%lld
Problem Description
     “快看,他就是那个世界冠军!”一个女生发现了小A,兴奋地告诉她的同伴。她们快步走上前去索要合照,小A无奈地配合照了一张。
    这种日子过得有一段时间了,起初还是蛮开心自豪地,后来就慢慢地厌烦了。小C也好长一段没有跟他联系了,不知道她去了哪里,心里一直都会想起她。很想拨通她的电话,但是每次拿起来又不敢打给她,因为不知道要说什么好。
    “对了,可以约她一起去买单反!”小A心里有了主意,就拨打了她的电话。
    “你好,是小C吗?”,“哦,小A啊,有什么事吗?”,“没事,那个…我想给你买单反,但是不知道怎么买,能不能一起去看看?”,“什么时候呢?”,“下午吧?”,“我想想…那好吧!”,“那下午见!”小A欣喜若狂地挂了电话。
    小A赶紧出去购物要买套好点的衣服,然后下午去见小C。走到商场的时候无意间看到了小C跟一个男的在逛街。小C赶忙躲开不让小A看到,心情甚是不爽,就回去了。
    下午2点左右的时候,小C打来电话,“你不是说要买单反吗?哪里会合呀?”。小A心情全无不想去买,但是又不想让小C发现有什么异常还是答应去,“不好意思,刚才有点事情差点给忘了,那就在宝虫大门口见吧~”,说完起身就出门了。
    见到了小C,强颜欢笑了下说,“上午忙什么呢?”。小C是个感觉非常敏锐的人,感觉似乎气氛有点不对,就反问到,“没什么,你呢?好像心情不好?”。小A感觉她似乎要隐瞒上午跟男生一起逛街的事情,就想提示她下,“最近许久不见,是不是跟男朋友哪里约会去喽~”。小C心里似乎明白了什么就说,“哪有男朋友啊,我不相信爱情!”小A心里高兴了一下,不过觉得这是借口,就继续调侃道,“怎么可能,你这么漂亮,我知道了,肯定是被甩过,深深地受伤了。现在肯定有N多的男生追你,我就看到你跟男生在一起…”小A赶紧停住,知道不小心说漏了嘴。小C明白过来,哈哈大笑起来,心想这家伙该不会是碰见我跟我哥在一起而吃醋了,便笑道“是呀,好多男生追,我都烦死了。还好今天我哥过来陪我聊天解我忧愁!”。“什么?今天那个是你哥?!!”小A兴奋地说道,不过又暴露了,连忙说到,“呃……没什么,我们还是说说单反吧!”。“好吧~”,小C无奈地说道。
    小A的心情顿时好了起来,便一起聊起单反,便说“单反有什么好的,比不上人的眼睛和大脑,上帝的设计真是让人敬畏啊!”。小C却不赞同,“单反拍了就能够存储起来,你看了过一段时间就忘了,想再看没了~~”。小A自豪地说到,“谁说的,我可是过目不忘,永不忘记,要不然咱们试试?”。小C便有点吃惊了,心想难道这小子真有这本事?这种人只是报纸上见过,难道今天有幸碰到一位?这世界冠军头衔也应该不是虚的,就想做个测试。
    小C想到了一个测试方法,小C说“我有个办法,我们逛街的时候看到的每个数字我都记录下来,等我们回去的时候我询问你我们看到的数字中有几个数字在我说的一个数字范围内,你若都答对就算你厉害!怎样?”。“好~!没问题!”小A欣然答应了。“不过在此之前要编个程序能够记录下看到的每个数字,然后回去的时候可以输出每个数字范围内有多少个数字来帮助我验证答案。”。“没问题”,说着小A就打出电脑动手编起来,一会儿就编好了。
    广告:“白死可乐”提醒你,本剧中他们看到的数字可达10万个,每个数字的范围是-10^9<=a[i]<=10^9,小C可能询问10万次,别问我那要询问多久,反正他们在一起很久很久~~
    他们逛了许久,回去之后凡询问的都正确回答出来,让小C惊叹不已。“怎样?我没有夸口吧!”。“看不出来,你还挺牛的呀!原谅小女子人眼看狗低!”小C嬉笑道。“你……”小A无奈。
    “咦咦咦呀…哦哦哦啊…啦啊啦啊啦…”这时小C的手机响了。“不好意思,接个电话…”,
过了许久,小C回来脸色似乎不太好看。“怎么啦?”小A疑问到。“没什么,我该回去了~”小C说着便开门回家了……

Input

 第一行是一个t表示有t组测试案例

每个案例的第一行是len表示看到的数字的个数(len<=100000)
下一行是len个数字,每个数字在[-10^9,10^9]区间内
接下来是一个整数q表示小C询问的次数,(0<q<=100000)
然后的q行每行是两个整数(x,y),(-10^9<=x<=y<=10^9)
Output

 对于每个询问,输出一个整数,表示看到的数字在询问的范围内的数的个数(包括x和y)

SampleInput
1
10
1 2 3 4 5 6 7 8 9 10
3
1 10
2 2
11 12
SampleOutput
10
1
0

此题就是搜索, 没什么好说的, 先排序。
接着 进行搜索。 注意的是, 数列里可能没有你找到的数。 此时只能进行模糊搜索, 找该数在数列中 是哪两个数 夹击着它( 不考虑边界情况下 )。 当然,
模糊二分搜索下, 边界搜索也是不正确的, 所以需要进行 边界判断, 矫正。
code:
#include <cstdio>
#include <algorithm>
#include <iostream>
using namespace std;
const int all = 100005;
int m[ all ];
int bin_find( int, int, int, bool );
int main(void)
{
    int t, n, st, en, d, tmp;
    //freopen( "E://test.txt", "rw+", stdin );
    scanf( "%d", &t );
    while( t -- )
    {
        scanf( "%d", &n );
        for( int i=1; i <= n; ++ i ){
            scanf( "%d", m+i );
        }

        sort( m+1, m+n+1 );
        scanf( "%d", &d );
        while( d -- ){
            scanf( "%d%d", &st, &en );
            tmp = st;
            if( ( en < m[1] || st > m[n] ) ){
                st = 0;
                en = 1;
            }
            else{
                st = tmp <= m[1] ? 0 : bin_find( 1, n, tmp, true );
                en = en >= m[n] ? n+1 : bin_find( 1, n, en, false );
            }
            printf( "%d\n", en-st-1 );
        }
    }
    return 0;
}

int bin_find( int l, int r, int num, bool isleft )
{
    if( r-l <= 1 ){
        if( isleft ){
            return l;
        }
        else{
            return r;
        }
    }

    if( isleft ){
        if( num == m[l] ){
            return l;
        }
    }
    else if( num == m[r] ){
        return r;
    }

    int mid = (l+r)/2;
    if( m[mid] == num ){
        if( isleft ){
            return bin_find( l, mid, num, isleft );
        }
        else{
            return bin_find( mid, r, num, isleft );
        }
    }

    else if( m[mid] < num ){
        return bin_find( mid, r, num, isleft );
    }

    else{
        return bin_find( l, mid, num, isleft );
    }
}
View Code

 

posted @ 2016-03-27 14:16  假大空  阅读(165)  评论(0编辑  收藏  举报