題目描述
給你乙個長度為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 轉導推理的目的是估計某一位置 函式在...