洛谷笔记 - P3799 妖梦拼木棒

不看题解的话……

根本没想到要用排列组合解……

难道不觉得很酷吗?很符合我对信奥的想象

题目背景

上道题中,妖梦斩了一地的木棒,现在她想要将木棒拼起来。

题目描述

nn 根木棒,现在从中选 44 根,想要组成一个正三角形,问有几种选法?

答案对 109+710^9+7 取模。

输入格式

第一行一个整数 nn

第二行往下 nn 行,每行 11 个整数,第 ii 个整数 aia_i 代表第 ii 根木棒的长度。

输出格式

一行一个整数代表答案。

样例 #1

样例输入 #1

1
2
3
4
5
4 
1
1
2
2

样例输出 #1

1
1

提示

数据规模与约定

对于 30%30\% 的数据,保证 n5×103n \le 5 \times 10^3

对于 100%100\% 的数据,保证 1n1051 \leq n \le 10^51ai5×1031 \le a_i \le 5 \times 10^3

代码段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// Problem: P3799 妖梦拼木棒
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P3799
// Memory Limit: 125 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)

//https://www.luogu.com.cn/record/95256641
//https://www.luogu.com.cn/record/95260815
//https://www.luogu.com.cn/record/95261441
//https://www.luogu.com.cn/record/95261932
//https://www.luogu.com.cn/record/96597614
//https://www.luogu.com.cn/record/96799377
//https://www.luogu.com.cn/record/96800038

#include<iostream>
#include<cmath>
using namespace std;
int b[100001];
const int mod=pow(10,9)+7;
long long ans=0;
int main(){
int a,maxl=-1;
cin>>a;
for(int i=1;i<=a;i++){
int tmp;
cin>>tmp;
maxl=max(maxl,tmp);
b[tmp]++;
}
for(int i=1;i<=maxl;i++){
for(int o=i;o<=maxl;o++){
if(i==o){
ans=(ans+(((b[i]*(b[i]-1))/2%mod)*(b[i+o]*(b[i+o]-1)/2%mod)))%mod;
//高中数学的排列组合 Example:C_5^2=A(5,2)/2=(5*4)/2=10;
//下文同理
}else ans=(ans+(((b[i]*b[o])%mod)*(b[i+o]*(b[i+o]-1))/2%mod))%mod; //早忘球了
}
}
cout<<ans<<endl;
return 0;
}

总结

数学是算法的基础,这回算是明白透了。