「查找表」观沧海

本题为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;
}

"正是我们每天反复做的事情,最终造就了我们,优秀不是一种行为,而是一种习惯" ---亚里士多德

posted @ 2022-12-28 10:54  星双子  阅读(35)  评论(0编辑  收藏  举报