abc269C - Submask(位运算)
abc269C - Submask(源地址自⇔Atcode)
tag
⇔位运算。
题意
给出一个数字 \(N\) ,输出所有满足条件的 \(X\) ,使得 \(X\) 的二进制位中 \(1\) 的排布是 \(N\) 的二进制位中 \(1\) 的排布的子集。
思路
个人思路
直接丢进 \(\tt DFS\) 里面,每次改一位 \(1\) 。使用 \(\tt bitset\) 简化运算。
大佬思路
裸的枚举子集,直接跑一遍 for (int i = x; i; i = (i - 1) & x)
这个循环即可。
AC代码
点击查看代码
个人思路
// Date: 2022-10-10 10:33:47
// Problem: C - Submask
// Contest: AtCoder - UNICORN Programming Contest 2022(AtCoder Beginner Contest 269)
// URL: https://atcoder.jp/contests/abc269/tasks/abc269_c
// Memory Limit: 1024 MB
// Time Limit: 2000 ms
// --------By WIDA--------
#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define int LL
const int N = 1e6 + 7;
set<int> ans;
void dfs(bitset<60> x) {
ans.insert(x.to_ullong());
for (int i = 0; i < 62; ++ i) {
if (x[i] == 0) continue;
x[i] = 0;
if (!ans.count(x.to_ullong())) dfs(x);
x[i] = 1;
}
}
signed main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int n; cin >> n;
bitset<60> B = n;
dfs(B);
for (auto it : ans) cout << it << "\n";
return 0;
}
大佬思路
#include <bits/stdc++.h>
#define int long long
using namespace std;
int x;
stack<int> st;
signed main() {
cin >> x;
for (int i = x; i; i = (i - 1) & x) st.push(i);
cout << 0 << endl;
while (!st.empty()) {
cout << st.top() << endl;
st.pop();
}
return 0;
}
错误次数:1
搜索前没有判断是否已经被搜索过,导致重复搜索,T。加上 if (!ans.count(x.to_ullong()))
即可。
文 / WIDA
2022.10.10 成文
首发于WIDA个人博客,仅供学习讨论