洛谷 P1102 A B 數對 三種解法

2021-10-23 04:16:30 字數 2051 閱讀 2328

給出一串數以及乙個數字 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,中間用空格隔開。第二行有...