quicksort+binarySearch

 

描述
数轴上有n个点,对于任一闭区间 [a, b],试计算落在其内的点数。

输入
第一行包括两个整数:点的总数n,查询的次数m。

第二行包含n个数,为各个点的坐标。

以下m行,各包含两个整数:查询区间的左、右边界a和b。

输出
对每次查询,输出落在闭区间[a, b]内点的个数。

Example
Input

5 2
1 3 7 9 11
4 6
7 12
Output

0
3

限制
0 ≤ n, m ≤ 5×105

对于次查询的区间[a, b],都有a ≤ b

各点的坐标互异

各点的坐标、查询区间的边界a、b,均为不超过10^7的非负整数

时间:2 sec

内存:256 MB
View Code

 

终于解决了《范围查询》算法这一题了,100分通过,得瑟一下! 经历了55分,45分,0分,runtime error的越改越少的怪圈,在此说下心得:

先scanf再用new来保存数组的输入值long;然后快速排序;

然后用二分查找,分别找左边界,右边界不同的情况

如果左边界为其中某个数a[i],则说明不包含的个数为i

如果右边界为其中某个数a[i],则说明包含的个数为i+1

用右边界包含的个数减去左边界不包含的个数,就是[a,b]内的个数

还有一种情况是边界点不在坐标数组中,也好分析。 

找不到那个数,最后一步情况就是low=middle=high,循环退出时是low>high。也可以算出左边不包含和右边包含的数的个数

用的VC6++,个人觉得关键点有: ,scanf, new long[n], quickSort, binarySearch, delete[]

 

  1 #include <cstdio> 
  2 //#include <stdlib.h> 
  3 //二分查找
  4 
  5 long binary_search(long* a, long len, long goal);
  6 void quicksort(long *a, long left, long right);
  7 
  8 //左边界T,右边界F
  9 long binary_search(long* a, long len, long goal, bool t)
 10 {
 11     long low = 0;
 12     long high = len - 1;
 13     long middle;
 14 
 15     while(low <= high)
 16     {
 17         middle = (low + high)/2;
 18         if(goal == a[middle])
 19         {
 20             return (t ? middle: middle+1);
 21         }
 22         else if(goal < a[middle])//在左半边
 23             high = middle - 1;
 24         
 25         else//在右半边
 26             low = middle + 1;
 27     }//low>high
 28     if(goal < a[middle])
 29         return middle;
 30     else//if (goal > a[middle])
 31         return middle + 1;
 32 }
 33 
 34 
 35 
 36 void quicksort(long *a, long left,long right) 
 37 { 
 38     long i,j,t,temp; 
 39     if(left>right) 
 40        return; 
 41                                 
 42     temp=a[left]; //temp中存的就是基准数 
 43     i=left; 
 44     j=right; 
 45     while(i<j) 
 46     { 
 47                    //顺序很重要,要先从右边开始找 小于基数的数
 48                    while(a[j]>=temp && i<j) 
 49                             j--; 
 50                    //再找左边的大于基数的数
 51                    while(a[i]<=temp && i<j) 
 52                             i++; 
 53                    //交换两个数在数组中的位置 
 54                    if(i<j) 
 55                    { 
 56                             t=a[i]; 
 57                             a[i]=a[j]; 
 58                             a[j]=t; 
 59                    } 
 60     } 
 61     //最终将基准数归位 
 62     a[left]=a[i]; 
 63     a[i]=temp; 
 64                              
 65     quicksort(a,left,i-1);//继续处理左边的,这里是一个递归的过程 
 66     quicksort(a,i+1,right);//继续处理右边的 ,这里是一个递归的过程 
 67 } 
 68 
 69 
 70 
 71 
 72 int main(void)
 73 {
 74     long num, cmd;
 75     long i,ret1,ret2;
 76 
 77     scanf("%ld %ld",&num,&cmd);
 78 
 79     //long *n = (long*)malloc(num*4);
 80     long *n = new long[num];
 81     for (i=0;i<num;i++)
 82         scanf("%ld ",n+i);
 83 
 84     //long *src = (long*)malloc(cmd*4);
 85     //long *des = (long*)malloc(cmd*4);
 86     long *src = new long[cmd];
 87     long *des = new long[cmd];
 88 
 89     for (i=0;i<cmd;i++)
 90         scanf("%ld %ld",src+i,des+i);
 91 
 92     quicksort(n, 0, num-1);
 93 
 94 /*    for (i=0;i<num;i++)
 95         printf("%d ",n[i]);*/
 96 
 97     for (i=0;i<cmd;i++)
 98     {
 99         ret1=binary_search(n,num,src[i],true);//find in n[], length num, goal src[i]
100         ret2=binary_search(n,num,des[i],false);
101         printf("%ld\n",ret2-ret1);
102     }
103 
104     delete[] n;
105     delete[] src;
106     delete[] des;
107     return 0;
108 }
View Code

 

posted @ 2015-09-24 11:49  jack-xu  阅读(177)  评论(0编辑  收藏  举报