1. 程式人生 > >luoguP3799 妖夢拼木棒 [組合數學]

luoguP3799 妖夢拼木棒 [組合數學]

組合數學 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 妖夢拼木棒 [組合數學]