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 }

浙公网安备 33010602011771号