給出一串數以及乙個數字 c,要求計算出所有 a - b = c 的數對的個數(不同位置的數字一樣的數對算不同的數對)。
1 ≤n
≤2×1
05
1≤n≤2×10^5
1≤n≤2×
105將式子變形可得 a - c = b ,那麼我們就可以將 b 中每個數出現的次數插入到map裡面,然後對於每乙個 a - c ,在map中找其出現的次數,累加到最終答案。
或者,我們可以在對b排序,在 b 中找到 a - c 的左右邊界,做差後累加到最終答案
亦或者,在排完序之後,對這個有序序列,我們可以使用雙指標演算法,維護兩個右端點 r1,
r2
r1 , r2
r1,r
2 , 每次 r1r1
r1右移到 a[r
1]−a
[l
]<
ca[r1] - a[l] < c
a[r1]−
a[l]
<
c 的最後位置的下一位,r2 右移到滿足 a[r
2]−a
[l
]<=c
a[r2] - a[l] <= c
a[r2]−
a[l]
<=c
最後一位。即a[r
1]
a[r1]
a[r1
]是第乙個滿足要求的元素,a[r
2]
a[r2]
a[r2
]是最後乙個滿足要求的元素的後乙個元素。
也就是說, 此時如果 a[r
1]−a
[l]=
=c
a[r1] - a[l] == c
a[r1]−
a[l]
==c&&a[r
2−1]
−a[l
]==c
a[r2-1] - a[l] == c
a[r2−1
]−a[
l]==
c,那麼中間的那一段一定都是滿足條件的,我們讓 ans
+=r2
−r
1ans += r2 - r1
ans+=r
2−r1
即可。採用map(400ms)
#include
using
namespace std;
int n,c;
unordered_map<
int,
int> m;
int a[
200005];
intmain()
long
long ans =0;
for(
int i =
1; i <= n;
++i)
cout << ans << endl;
return0;
}
使用二分(測評顯示二分更快一點 300ms)
#include
using
namespace std;
int n,c;
int a[
200005];
intbsearchleft
(int key)
return a[l]
==key?l:0;
}int
bsearchright
(int key)
return a[l-1]
==key?l-1:
0;}int
main()
cout << ans << endl;
return0;
}
採用雙指標演算法(測評表明該演算法最快 240ms)
#include
using
namespace std;
int n,c;
int a[
200005];
intmain()
cout << ans << endl;
return0;
}
洛谷P1102 A B 數對
題目描述 出題是一件痛苦的事情!相同的題目看多了也會有審美疲勞,於是我捨棄了大家所熟悉的 a b problem,改用 a b 了哈哈!好吧,題目是這樣的 給出一串數以及乙個數字 c,要求計算出所有 a b c 的數對的個數 不同位置的數字一樣的數對算不同的數對 輸入格式 輸入共兩行。第一行,兩個整...
洛谷 P1102 A B 數對 題解
鏈結 出題是一件痛苦的事情!相同的題目看多了也會有審美疲勞,於是我捨棄了大家所熟悉的 a b problem,改用 a b 了哈哈!好吧,題目是這樣的 給出一串數以及乙個數字 c cc,要求計算出所有 a b c a b c a b c的數對的個數 不同位置的數字一樣的數對算不同的數對 輸入共兩行。...
洛谷 P1102 A B數對 題解
出題是一件痛苦的事情!題目看多了也有審美疲勞,於是我捨棄了大家所熟悉的 a b problem,改用 a b 了哈哈!好吧,題目是這樣的 給出一串數以及乙個數字 c,要求計算出所有 a b c 的數對的個數。不同位置的數字一樣的數對算不同的數對 第一行包括2個非負整數n和c,中間用空格隔開。第二行有...