差(二分查詢)
阿新 • • 發佈:2018-12-23
題目描述
楠楠在網上刷題,感覺第一題:求兩數的和(A+B Problem)太無聊了,於是增加了一題:A-B Problem,難倒了一群小朋友,哈哈。
題目是這樣的:給出N個從小到大排好序的整數,一個差值C,要求在這N個整數中找兩個數A和B,使得A-B=C,問這樣的方案有多少種?
例如:N=5,C=2,5個整數是:2 2 4 8 10。答案是3。具體方案:第3個數減第1個數;第3個數減第2個數;第5個數減第4個數。
輸入
第一行2個正整數:N,C。
第二行N個整數:已經有序。注意:可能有相同的。
輸出
一個整數,表示該串數中包含的所有滿足A-B=C的數對的方案數。
樣例輸入
複製樣例資料
4 1
1 1 2 2
樣例輸出
4
提示
5個數據:N的範圍是[1…1,000]。
5個數據:N的範圍是[1…100,000]。
所有資料:
C的範圍是[1…1,000,000,000]。
N個整數中每個數的範圍是:[0…1,000,000,000]。
這題一開始看到1e9真沒想到二分能過(因為我想它再怎麼分那1e9的for迴圈還是要走的,可能是資料水了),最基礎的二分跑一遍就行了。
#include<iostream> using namespace std; int sum=0; int num[10000005]; int main(int argc, char const *argv[]) { int n,m; while(~scanf("%d%d",&n,&m)) { sum=0; for(int i=0;i<n;i++) { scanf("%d",&num[i]); } for(int k=0;k<n;k++) { int c=num[k]+m; int i=0,j=n-1; while(i<=j) { int mid=(i+j)/2; if(num[mid]==c) { sum++; int p=mid-1; while(num[p]==c&&p>=0) { p--; sum++; } p=mid+1; while(num[p]==c&&p<n) { p++; sum++; } break; } else if(num[mid]>c) j=mid-1; else i=mid+1; } } printf("%d\n",sum); } return 0; }
//最後附上一個最最基礎的二分模板。
int dls(int num[],int n,int want_to_find) { int i=0,j=n-1; while(i<=j) { int mid=(i+j)/2; if(num[mid]==want_to_find) { return mid; //返回下標 } else if(num[mid]>want_to_find) { j=mid-1; } else { i=mid+1; } } return -1; //如果找不到就返回-1 }