P1102 A B 數對(詳解,可以過AC)

2021-10-09 20:12:31 字數 1886 閱讀 9319

題目描述

出題是一件痛苦的事情!

相同的題目看多了也會有審美疲勞,於是我捨棄了大家所熟悉的 a+b problem,改用 a-b 了哈哈!

好吧,題目是這樣的:給出一串數以及乙個數字 cc,要求計算出所有 a - b = ca−b=c 的數對的個數(不同位置的數字一樣的數對算不同的數對)。

輸入格式

輸入共兩行。

第一行,兩個整數 n, cn,c。

第二行,nn 個整數,作為要求處理的那串數。

輸出格式

一行,表示該串數中包含的滿足 a - b = ca−b=c 的數對的個數。

輸入輸出樣例

輸入 #1 複製

4 11 1 2 3

輸出 #1 複製

3說明/提示

對於 75%75% 的資料,1 \leq n \leq 20001≤n≤2000。

對於 100%100% 的資料,1 \leq n \leq 2 \times 10^51≤n≤2×105。

保證所有輸入資料都在 3232 位帶符號整數範圍內。

新添資料兩組

思路:這道題新添的資料好麻煩有點難過,先試用陣列

我們要用sort來給那堆數排序

然後讓乙個個數進入陣列

這個時候第乙個引數就是記錄看到底有多少個重複一樣的用p表示

p表示的不是當前跟自己重複的是多少個,比如題目給的序列是1 1 2 3,那麼看到2的時候p記錄的是前面 1 有2個重複

這個時候判斷2-1=1,那麼答案就加2,(那麼s=s+p)

如果是1 1 1 2 3,那麼迴圈到第四個數字2的時候,答案就加3

如果是1 1 1 2 2 3,迴圈到第四個答案加3,迴圈到第五個數字,發現它和前面一樣,也加3,因為有兩個2乙個和前面三個組成一組答案

然後,我們需要乙個新的佇列,如果當前數字和前乙個一樣,那麼我們就每乙個都加入佇列

知道遇到跟前乙個不一樣的,比如 1 1 1 2 3,這個時候遇到2,佇列裡面有三個數字 1 1 1

那麼只要這個佇列不為空,就從佇列頭看起,如果 2 - 佇列頭 = 1那就 p++

比如 1 1 1 4 5 5 6

迴圈到4,發現佇列頭小於3

那麼把佇列頭乙個乙個彈出(但是我們用的不是佇列,這就用第乙個while迴圈的作用,去除前面佇列頭太小的時候進行清除之前一樣的數字)

彈出的時候p沒有加加,然後佇列就彈完了

之前那個如果是1的p加加之後還是要繼續彈出隊頭

然後 2也得進隊

也就是說我們的總體思想是,每乙個元素都進隊

但是如果你和前面的元素一樣,就不需要執行什麼判斷了

如果你和前面的元素不一樣,這個時候就要執行判斷,看看排在你前面的隊頭有多少個跟你相差1

前面比你小的剛好1的判斷完就全部彈出去了

或者如果前面全部沒有剛好是1,那就彈到你之前沒有數字

相當於隊尾進乙個數字,就看看要不要把前面的人推出去

這種思想去找答案

ac**:

#include

#include

#include

#include

using

namespace std;

int m,n,a[

2000020

],zi[

2000020

],c;

long

long s=0;

intmain()

else

p=0;

while

(front==a[i]

-c)//下乙個數,跟前面陣列頭不相同的數字

zi[reat]

=a[i]

; reat++

; s=s+p;}}

cout

}

洛谷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 數對(二分)

p1102 a b 數對 出題是一件痛苦的事情!相同的題目看多了也會有審美疲勞,於是我捨棄了大家所熟悉的 a b problem,改用 a b 了哈哈!好吧,題目是這樣的 給出一串數以及乙個數字 c,要求計算出所有 a b c 的數對的個數 不同位置的數字一樣的數對算不同的數對 輸入共兩行。第一行,...