构造专栏的第一个题哈
题目链接
给定 n n n根木棒,第 i i i根权值为 a [ i ] a[i] a[i],长度为 2 2 2的 a [ i ] a[i] a[i]次方,要求从 n n n根木棒中找到最多种能拼成合法三角形的方法,输出种类
长度为
2
,
4
,
8
,
16...
2,4,8,16...
2,4,8,16...显然三边要么两长加一短,要么三个一样长的,即等边或者等腰,所以我们用
m
a
p
map
map存各长度的数量
大于等于三个的先内部消化(选出
3
3
3个),大于等于两个的需要内部选出
2
2
2个和别的短的配合,一个的只能配合。
我们知道,本题需要的等腰为两长边加一短边,而
m
a
p
map
map内部初始存储为,先按
k
e
y
key
key从小到大,再
v
a
l
u
e
value
value从小到大(字典序),所以我们可以放心累加把小的当成短边
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
void solve()
{
map<int, int>mp;
int n;cin >> n;
int p;
for (int i = 1;i <= n;i++) {
cin >> p;
mp[p]++;
}
ll ret = 0;
ll num = 0;
for (auto x : mp) {//这里不能用auto [x,y]:mp,会数据溢出
ll y = x.second;
if (y >= 3)ret += y * (y - 1) * (y - 2) / 6;
if (y >= 2)ret += y * (y - 1) / 2 * num;
num += y;
}
cout << ret << '\n';
}
int main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t;cin >> t;
while (t--) {
solve();
}
return 0;
}