「查找表」观沧海
本题为12月28日22寒假集训每日一题题解
题目来源:(未知)
题面
题目描述
《观沧海》曹操
东临碣石,以观沧海。
水何澹澹,山岛竦峙。
树木丛生,百草丰茂。
秋风萧瑟,洪波涌起。
日月之行,若出其中;
星汉灿烂,若出其里。
幸甚至哉,歌以咏志。
话说曹操,写完这首诗后,看到星光灿烂的星空,发现很多颗星星可以组成正三角形。
等边三角形又称为正三角形,是指三条边相等的三角形。
你的任务:对于给定的N个正整数(代表三角形的边长),统计能够组成等边三角形的个数。
输入
第一行:N
第二行:N个正整数,相互之间用空格隔开。
输出
一行,为等边三角形的个数;如果拼不出等边三角形,输出“None”(不含引号)。
样例输入
【样例输入1】
5
3 2 3 3 3
【样例输入2】
5
1 2 3 4 5
样例输出
【样例输出1】
1
【样例输出2】
None
提示
对于 70% 的数据:1≤N≤10000,1≤边长≤100。
对于 100% 的数据:1≤N≤1000000,1≤边长≤10000。
思路分析
此题请直接正常做,不要发挥想象,什么5条边可以拼成<|>这个形状,可以有2个等边三角形啥的.题目说的是给你这几条边,能组成几个等边三角形,不是能拼成含有几个等边三角形的图形,更不是有几种拼成等边三角形的拼法.
显然,看有多少个等边三角形,就是看有多少组边出现了3的几倍次.也就是我们需要一种数据结构来记录每条边出现的次数,以便不断进行更新和获取.
这里边长的上限是10000,所以直接使用一个数组作为桶
即可.
这里我出于个人习惯,选择了哈希表
.其实桶本身也可以看成一种特殊的哈希表,所以两种写法本质上是差不多的.直接用桶
的算法效率其实会更高.
参考代码
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3, "Ofast", "inline")
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
unordered_map<int, int> hashmap; // 存放每种边长出现的次数
int n;
cin >> n;
while (n--)
{
int a;
cin >> a;
hashmap[a]++; // 把此边长出现的次数自增(会自动从0开始自增)
}
int res = 0;
for (auto &i : hashmap) // 遍历哈希表,此处i的类型为pair
{
if (i.second >= 3) // 当前边长出现次数大于等于3次,可以组成等边三角形
{
res += i.second / 3; // 每3个相等的边能组成一个等边三角形,总数加上当前边数整除以三即可
}
}
if (res)
{
cout << res << "\n";
}
else
{
cout << "None\n";
}
return 0;
}
"正是我们每天反复做的事情,最终造就了我们,优秀不是一种行为,而是一种习惯" ---亚里士多德
这里是浙江理工大学22届ACM集训队的成员一枚鸭!
本文首发于博客园,作者:星双子,除了我自己的转载请注明原文链接:https://www.cnblogs.com/geministar/p/zstu22_12_28.html