P3799 小 Y 拼木棒
题目背景
上道题中,小 Y 斩了一地的木棒,现在她想要将木棒拼起来。
题目描述
有 nnn 根木棒,现在从中选 444 根,想要组成一个正三角形,问有几种选法?
答案对 109+710^9+7109+7 取模。
输入格式
第一行一个整数 nnn。
第二行往下 nnn 行,每行 111 个整数,第 iii 个整数 aia_iai 代表第 iii 根木棒的长度。
输出格式
一行一个整数代表答案。
输入输出样例 #1
输入 #1
4
1
1
2
2
输出 #1
1
说明/提示
数据规模与约定
- 对于 30%30\%30% 的数据,保证 n≤5×103n \le 5 \times 10^3n≤5×103。
- 对于 100%100\%100% 的数据,保证 1≤n≤1051 \leq n \le 10^51≤n≤105,1≤ai≤5×1031 \le a_i \le 5 \times 10^31≤ai≤5×103。
关于标题:因为一些不可抗力的原因,名称进行了更改。深表歉意。
C++实现
#include <cstdio>
#include <algorithm>
#define ll long long
using namespace std;
const int kMaxn = 1e6 + 10;
const ll kMod = 1e9 + 7;
ll n, ans, maxa, a[kMaxn], num[kMaxn];
ll C(ll x, ll k) {
return (k == 1ll ? x : x * (x - 1ll) / 2ll) % kMod;
}
int main() {
scanf("%lld\n", &n);
for (int i = 1; i <= n; ++ i) { //读入,并放入计数数组中
scanf("%lld", &a[i]);
maxa = max(a[i], maxa);
num[a[i]] ++;
}
for (int i = 2; i <= maxa; ++ i) { //枚举两根相等的边
if (num[i] >= 2ll) {
ll times = C(num[i], 2ll) % kMod; //求出组合数
for (int j = 1; j <= i / 2; ++ j) { //枚举被合成的边(到i / 2即可)
if (j != i - j && num[j] >= 1 && num[i - j] >= 1) //用来合成的木棒长度不等
ans += times * C(num[j], 1) * C(num[i - j], 1) % kMod;
if (j == i - j && num[j] >= 2) //用来合成的木棒长度相等
ans += times * C(num[j], 2) % kMod;
ans %= kMod;
}
}
}
printf("%lld", ans);
return 0;
}

后续
接下来我会不断用C++来实现信奥比赛中的算法题、GESP考级编程题实现、白名单赛事考题实现,记录日常的编程生活、比赛心得,感兴趣的请关注,我后续将继续分享相关内容
537

被折叠的 条评论
为什么被折叠?



