1. 程式人生 > 實用技巧 >P1102 A-B數對 (二分查詢)

P1102 A-B數對 (二分查詢)

題目連結:P1102

解題思路:

要找A-B=C,變成A=B+C,將數排序,遍歷每一個數,用二分查詢檢視是否存在B+C,因為不同位置數字算不同一對,所以要特殊處理,開陣列記錄的話可能會MLE,所以用map來存數字出現次數

AC程式碼:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <map>
 5 #define ll long long
 6 using namespace std;
 7 ll n,c,mx,cnt,a[300010];
8 inline ll read() // 快讀 9 { 10 ll x = 0,y = 1; char c = getchar(); 11 while(c < '0' || c > '9') {if(c == '-') y = -1; c = getchar();} 12 while(c >= '0' && c <= '9') x = x*10+c-'0', c = getchar(); 13 return x*y; 14 } 15 bool bfind(ll x) // 二分 16 { 17 int l = 0, r = n-1
; 18 int mid = (r-l)/2+l; 19 while(true) 20 { 21 if(l == r) 22 { 23 if(a[l] == x) return true; 24 else return false; 25 } 26 if(a[mid] >= x) 27 { 28 r = mid; 29 mid = (r-l)/2+l; 30 } else if(a[mid] < x) {
31 l = mid+1; 32 mid = (r-l)/2+l; 33 } 34 } 35 } 36 int main() 37 { 38 map<ll, ll> m; 39 cnt = 0; 40 n = read(); 41 c = read(); 42 for(int i = 0; i < n; i++) 43 { 44 a[i] = read(); 45 m[a[i]]++; // 記錄出現次數 46 } 47 sort(a,a+n); 48 mx = a[n-1]; // 記錄一下最大值 49 for(int i = 0; i < n; i++) 50 { 51 if(a[i]+c > mx) continue; // 如果超過最大值,就沒必要去查找了 52 else if(bfind(a[i]+c)) 53 cnt += 1*m[a[i]+c]; // 算不同位置的對數 54 } 55 printf("%lld",cnt); 56 return 0; 57 }