3750: 二分查找
Time Limit(Common/Java):3000MS/9000MS Memory Limit:65536KByte
Total Submit: 1925 Accepted:759
Total Submit: 1925 Accepted:759
Description
将n个从小到大排序的整数(n<1000000)从1~n进行编号,并一个待查找的整数m,请使用二分法进行查找。
Input
输入包括3行,第一行为整数n,第二行包括n个整数,以空格分隔,第三行为整数m。
Output
如果能够在序列中找到整数m,则输出编号(如果存在多个编号,返回编号最小的),如果不存在,则输出None。
Sample Input
10
1 2 4 5 6 7 8 9 10 11
10
10
1 2 4 5 6 7 8 9 10 11
12
Sample Output
9
None
一个二分查找的数据结构题,第一次我竟然TLE了,这个会有重复的啊,所以重复我就向前搜索,这个TLE可能是我查询到中间的时候他就找到了,但是这个数确很靠前,所以借助了辅助数组就过了,那这个题也可以测试下移位运算符啊,但是我觉得这个移位运算符并没有快多少,所以我要想缩短时间还可以用lower_bound,但是速度也是没有提升太多的。想一下用map去重,map插入运算本来就要耗时,所以还是TLE了,所以好奇怪第一名究竟用了什么做法
一般二分
#include <stdio.h> int a[1000005],b[1000005],n,t; int BS(){ int l=0,r=n-1; while(l<=r) { int m=(l+r)>>1; if(t<a[m]) r=m-1; else { if(t>a[m]) l=m+1; else return m; } } return -1; } int main(){ while(~scanf("%d",&n)){ scanf("%d",&a[0]); b[0]=1; for(int i=1;i<n;i++){ scanf("%d",&a[i]); if(a[i]==a[i-1]) b[i]=b[i-1]; else b[i]=i+1;} scanf("%d",&t); if(a[0]==t) puts("1"); else{ int f=BS(); if(f!=-1){ printf("%d\n",b[f]); } else puts("None"); }} return 0; }
上面的二分用空间过多,继续二分下去,也就是看下左边和它相等么,但是这个速度也上不去,改下哈夫曼树的不同判断也不行
#include <stdio.h> int a[1000005],n,t; int BS(){ int l=0,r=n-1; while(l<=r){ int m=(l+r)>>1; if(t<a[m]) r=m-1; else if(t>a[m]) l=m+1; else if(a[m-1]<t) return m; else r=m-1; } return -1; } int main(){ while(~scanf("%d",&n)){ for(int i=0;i<n;i++) scanf("%d",&a[i]); scanf("%d",&t); if(a[0]==t) puts("1"); else{ int f=BS(); if(f!=-1){ printf("%d\n",f+1); } else puts("None"); }} return 0; }
库函数提供的二分
#include <stdio.h> #include <algorithm> using namespace std; int a[1000000],n,t; int main(){ while(~scanf("%d",&n)){ for(int i=0;i<n;i++) scanf("%d",&a[i]); scanf("%d",&t); int f=lower_bound(a,a+n,t)-a; if(a[f]==t) printf("%d\n",f+1); else printf("None\n"); } return 0; }