陣列配對 推理

2021-10-03 00:19:16 字數 1299 閱讀 4683

題目描述

給你乙個長度為n的陣列a和乙個正整數k,問從陣列中任選兩個數使其和是k的倍數,問有多少種選法?對於陣列a1=1,a2=2,a3=2而言:

1.(a1,a2)和(a2,a1)是同一種選法;

2.(a1,a2)和(a1,a3)不是同一種選法;

input

第一行輸入兩個整數n,k;n<1000000,k<1000 第二行有n個正整數,每個正整數的大小不超過1e9;

5 61 2 3 4 5

output

輸出多少種選法?

2思路:

暴力列舉陣列中任意兩個元素的組合;使其滿足(a[i]+a[j])%k==0,一定注意n種選法,n可能超過int,這是乙個排列組合 ∁

\complement∁2n

2 \atop n

n2​=n(n-1)/2.

**1(n²)

#include

typedef

long

long ll;

const

int maxn=

1e6+5;

int arr[maxn]

;int

main()

當n為1e6時,n²就會是1e12,程式將會跑的很慢很慢。怎麼來優化演算法呢?這裡提到乙個公式(ai+aj)%k=0,(ai%k+aj%k)%k=0;這是解這個題的關鍵,那麼就可以把問題縮小化,也就是求0~k-1中的陣列對和是k即可。當把陣列縮小後,會呈現一定的規律,bi和b(k-i)是乙個陣列對,很簡單假設陣列為6,7,8,9,10時,倍數為6,縮小陣列後為0,1,2,3,4,那麼第2個(從0開始的哦)和第4個就是成對出現的,因此陣列對分配在陣列兩邊。

(1).j∁

\complement∁2n

2 \atop n

n2​(3).i**2(n)

#include

typedef

long

long ll;

const

int maxn=

1e6+5;

int arr[maxn]

;int

main()

ll ans=0;

//這裡一定要注意次數爆int,從n中隨機選取兩個,在高中我們都學過組合吧,cn2,也就是n(n-1)/2;

for(

int i=

0;i)printf

("%d\n"

,ans)

;return0;

}

這個題還是有很多需要注意的點,例如ai*aj容易爆int,所以要強制型別轉換。

基礎演算法 陣列配對

description 陣列配對任務描述 給你乙個長度為n的陣列a和乙個正整數k,問從陣列中任選兩個數使其和是k的倍數,有多少種選法對於陣列a1 1,a2 2,a3 2而言 a1,a2 和 a2,a1 被認為是同一種選法 input 輸入n,k,n 1000000,k 1000,第二行有n個整數,大...

GZOI 2017配對統計 樹狀陣列

最開始讀題的時候沒有讀的太懂,以為i是在選定區間內給的,實際上不是,這道題的意思應該是在l和r的區間內找出有多少個好的配對,這裡好的配對是對於整個區間來說的,既然是對於整個區間,我們就不難想到找出好的配對的方法,所以我們可以先找出所有好的配對,然後用樹狀陣列維護個數。如何找出好的配對呢?我們先來分析...

轉導推理 歸納推理 轉導學習

轉導推理 歸納推理 def 傳統推理方法 歸納推理 直到今天,傳統的推理方法仍然是歸納 演繹法,人們首先用已有資訊定義乙個一般規則,然後用這個規則來推斷所需要的答案 首先從特殊到一般,然後從一般特殊。def 轉導推理 transductive inference 轉導推理的目的是估計某一位置 函式在...