E1. Close Tuples (easy version)

博客内容主要介绍了如何利用C++编程解决一个算法问题,即统计数组中每个元素出现的次数,并根据出现次数计算可以形成的特定组合。通过遍历一个映射(map)来记录每个数字的频率,然后根据计数计算可以组成三个相同数字的组合,以及两个相同数字加一个相邻数字的组合。博主特别提到了需要考虑整型溢出问题,以及在计算过程中更新映射以避免重复计数的重要性。
摘要由CSDN通过智能技术生成

题目

原谅兄弟我只A了easy…所以就写个easy的题解吧…

思路:用一个map记录各个值的次数,然后如果某数字数量>=3则可以构成n*(n-1)(n-2)个相同的3个数组成的元组,如果某数字(a)数量>=2则可以构成n(n-1)/2*(a-1的数量+a-2的数量+a+1的数量+a+2的数量)个两个数字为a,其余一个为a+1或a-1或a+2或a-2的元组,如果某数字a的数量>=1则可以构成a的数量a-1的数量a+1的数量三个数字不同(a-1,a,a+1)的元组。对了,还要注意下开long long,因为两个2e5相乘会爆int,我因此还wa了一发。

Code:

#include<iostream>
#include<string>
#include<map>
#include<algorithm>
#include<memory.h>
#include<cmath>
#include<bitset>
#define pii pair<int,int>
#define FAST ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
typedef long long ll;
const int Max = 1e6 + 5;
int lst[Max];
int Mod = 1e9 + 7;


int main()
{
	FAST;
	int t;cin >> t;
	while (t--)
	{
		ll n;cin >> n;
		map<ll, ll> ma;
		for (int i = 1;i <= n;i++)
		{
			int g;cin >> g;
			ma[g]++;
		}
		ll sum = 0;
		for (auto i = ma.begin();i != ma.end();i++)
		{
			if (i->second >= 3)
			{
				ll p = i->second;
				sum += (p * (p - 1) * (p - 2) / 6);
			}
			ll p = i->first;
			sum += (ma[p - 1] * ma[p] * ma[p + 1]);
			if (i->second >= 2)
			{
				sum += ((ma[p] * (ma[p] - 1) / 2) * (ma[p - 1] + ma[p + 1]+ma[p+2]+ma[p-2]));
			}
			if (ma[p - 1] == 0)ma.erase(ma.find(p - 1));
			if (ma[p + 1] == 0)ma.erase(ma.find(p + 1));
			if (ma[p + 2] == 0)ma.erase(ma.find(p + 2));
			if (ma[p -2] == 0)ma.erase(ma.find(p -2));
		}
		cout << sum << endl;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_Rikka_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值