F. 3SUM

题目:

 样例:

输入
6
4
20 22 19 84
4
1 11 1 2022
4
1100 1100 1100 1111
5
12 34 56 78 90
4
1 9 8 4
6
16 38 94 25 18 99

输出
YES
YES
NO
NO
YES
YES

解题思路:

         这道题很好玩,找出任意 三个元素,相加有没有结果个位数为 3 的三个元素

这里我们三重循环个位数 0~9相加即可,输入的时候统计每个元素的相应的个位数,该个位数共有多少个,然后暴力枚举一遍可以了

代码详解如下:

#include <iostream>
#include <unordered_map>
#define endl '\n'
#define YES puts("YES")
#define NO puts("NO")
#define umap unordered_map
#pragma GCC optimize(3,"Ofast","inline")
#define ___G std::ios::sync_with_stdio(false),cin.tie(0), cout.tie(0)
using namespace std;
const int N = 2e6 + 10;

int n, sum;
umap<int, int>r;	// 用于记录我们数组元素中个位数出现的次数

inline void solve()
{
	//清空之前的记录
	r.clear();

	cin >> n;
	for (int i = 0, x; i < n; ++i)
	{
		cin >> x;

		// 由于结果只要个位数是 3,所以只有个位数有关系
		// 取出个位数
		x %= 10;

		// 记录好该数值有多少个
		r[x]++;

		// 这里来个小优化,记录所有个位数的总和
		sum += x;
	}

	// 如果所有个数都不可能超过 3 说明是 NO
	if (sum < 3)
	{
		NO;
		return ;
	}

	sum = 0;	// 初始化所有总和


	// 暴力枚举所有可能的个位数
	for (int i = 0; i < 10; ++i)
	{
		for (int j = i; j < 10; ++j)
		{
			for (int k = j; k < 10; ++k)
			{
				r[i]--, r[j]--, r[k]--;	// 取出我们枚举的数值
				if ((i + j + k) % 10 == 3 && r[i] >= 0 && r[j] >= 0 && r[k] >= 0)
				{
					YES;
					return ;
				}

				// 由于不符合,所以放回去,恢复我们取出来
				r[i]++, r[j]++, r[k]++;
			}
		}
	}
	NO;
}


int main()
{
//	freopen("a.txt", "r", stdin);
	___G;
	int _t = 1;
	cin >> _t;
	while (_t--)
	{
		solve();
	}

	return 0;
}

 最后提交:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值