TOJ 3750: 二分查找
阿新 • • 發佈:2017-06-08
沒有 編號 移位 target pri http rip put scanf
Total Submit: 1925 Accepted:759
3750: 二分查找
Time Limit(Common/Java):3000MS/9000MS Memory Limit:65536KByteTotal 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; }
TOJ 3750: 二分查找