題目: UVa - 11286 - Conformity

題目說明

每組測資會給一個整數,代表接下來會有幾組課程代號,每組課程代號會有五個代號,代表某個學生選擇的五堂課,求最多人選擇的組合。

Input: 每組測資起始於一個整數 n,若 n 為 0 代表結束。否則接下來 n 行中,每行會有 5 個 3 位數的整數代表課程代號,中間以空格隔開。每組測資中間沒有空行,整數與課程代號中也沒有空行。

Output: 求最多人選擇的那組課程代號的人數,若同時有超過一組最多人選擇的話則將人數相加,例如 Sample 的第二組資料,有三組不同的組合則答案為 1 + 1 + 1 = 3

解題思路

想法: 整體思路為,將每個人選擇的課程代號以小到大排序,即可避免順序不同但組合相同的問題,接著使用 Unordered_map 記數,最後遍歷找出答案即可。

作法: 先讀取 n,接下來每一行使用 cin 讀取課程代號,並先存放到一個 Vector,讀取 5 個後先對 Vector 進行排序,最後把它存放到一個 String 裡面當作 key,接著將 key 對應的 val 加一即可。讀取完後遍歷 map,使用 pair 來儲存結果,first 為當前選擇的組合的人數,second 為與 first 人數相同的課程代號的總和,每遍歷到一組資料,先判斷是否大於原本的 first,若大於則代表應該選擇當前的組合的人數,更新 first 及 second,否則若是與 first 相等,則將 second 加上當前的人數,最後輸出結果即可。

參考解法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <unordered_map>

using namespace std;

// fast IO
static auto __ = []()
{
std::ios_base::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cout.tie(nullptr);
return 0;
}();

int main()
{
int n;
while (cin >> n && n)
{
unordered_map<string, int> m;

while (n--)
{
string str;
vector<string> v;
for (int i = 0; i < 5; ++i) cin >> str, v.emplace_back(str);
sort(begin(v), end(v));
str.clear();
for (auto& s : v) str += s;
++m[str];
}

pair<int, int> ret;
for (auto& [k, v] : m)
{
if (v > ret.first) ret = { v, v };
else if (v == ret.first) ret.second += v;
}

cout << ret.second << '\n';
}
}