目录
- 题目
- 算法标签: 枚举, 位运算优化, 模拟
- 思路
- 代码
题目
CF442A Borya and Hanabi
算法标签: 枚举, 位运算优化, 模拟
思路
注意到, 颜色数量和数字数量都是 5 5 5, 因此可以使用位运算枚举需要选择的颜色数量和数字数量, 如果能将所有牌覆盖到, 那么当前方案就是一个合法的方案可以更新 a n s ans ans, 但是因为牌是可能有重复的, 需要开一个 s e t set set对牌进行去重, 需要将二维信息映射到一维, 也就是 a × 10 + b a \times 10 + b a×10+b每一种牌生成唯一的哈希值, 然后枚举所有的颜色和数字的选择情况
代码
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <map>
#include <set>using namespace std;const int M = 1 << 5, INF = 0x3f3f3f3f;int get(int x) {int ans = 0;for (int i = 0; i < 5; ++i) {ans += x >> i & 1;}return ans;
}int main() {ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);int n;cin >> n;map<char, int> mp;mp['R'] = 0;mp['G'] = 1;mp['B'] = 2;mp['Y'] = 3;mp['W'] = 4;set<int> st;for (int i = 0; i < n; ++i) {string s;cin >> s;int col = mp[s[0]];int val = s[1] - '1';st.insert(col * 10 + val);}n = st.size();int ans = INF;// 枚举所有颜色选择情况for (int i = 0; i < M; ++i) {// 枚举所有数字选择情况for (int j = 0; j < M; ++j) {set<int> vis;// 枚举所有牌for (auto &x : st) {int curr = 0;int col = x / 10;int val = x % 10;if (i >> col & 1) {curr += (col + 1) * 10;}if (j >> val & 1) {curr += val + 1;}vis.insert(curr);}if (vis.size() == n) {int cnt = get(i) + get(j);ans = min(ans, cnt);}}}cout << ans << "\n";return 0;
}