luoguP3799 妖夢拼木棒 [組合數學]
阿新 • • 發佈:2017-08-04
組合數學 strong 長度 輸出格式 stream 一行 iostream urn tdi
題目背景
上道題中,妖夢斬了一地的木棒,現在她想要將木棒拼起來。
題目描述
有n根木棒,現在從中選4根,想要組成一個正三角形,問有幾種選法?
輸入輸出格式
輸入格式:
第一行一個整數n
第二行n個整數,a1,a2,……an(0<ai<=5000),代表每根木棒的長度。
輸出格式:
一行一個整數,對1e9+7取模
輸入輸出樣例
輸入樣例#1:4 1 1 2 2輸出樣例#1:
1
說明
對於30%的數據 N<=5000
對於100%的數據 N<=100000
木棍長度可以用桶存儲
考慮枚舉長木棍l1和短木棍l2,三角形由兩種長度的木棍(l1,l1,l2,l2)或三種長度(l1,l1,l2,(l1-l2))的木棍拼成。
組合數學!
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 using namespace std; 5 6 typedef long long ll; 7 8 const int maxsiz=5005; 9 const int mod=1e9+7; 10 11 int n; 12 int buc[maxsiz]; 13 ll ans; 14 15 int C1(int x){ 16 return x; 17 }18 19 int C2(int x){ 20 return 1ll*x*(x-1)/2%mod; 21 } 22 23 int main(){ 24 scanf("%d",&n); 25 for(int i=0,tmp;i<n;i++){ 26 scanf("%d",&tmp); 27 buc[tmp]++; 28 } 29 for(int i=2;i<=5000;i++){ 30 if(buc[i]>=2) 31 for(int j=1;j<=i/2;j++){ 32 int k=i-j; 33 if(k==j){ 34 if(buc[j]>=2) 35 ans=(1ll*C2(buc[i])*C2(buc[j])%mod+ans)%mod; 36 } 37 else{ 38 if(buc[j]&&buc[k]) 39 ans=(1ll*C2(buc[i])*C1(buc[j])*C1(buc[k])%mod+ans)%mod; 40 } 41 } 42 } 43 printf("%d\n",ans); 44 return 0; 45 }
luoguP3799 妖夢拼木棒 [組合數學]