ABC 269 C - Submask(dfs+位运算)
C - Submask(dfs+位运算)
题目大意:
给定一个十进制的数字,让我们求出它的二进制下的1可以改变时候的数字
Sample Input 1
11
Sample Output 1
0
1
2
3
8
9
10
11
The binary representation of N=11 (10)==1011 (2).
The non-negative integers x that satisfy the condition are:
0000 (2)=0 (10)
0001 (2)=1 (10)
0010 (2)=2 (10)
0011 (2)=3 (10)
1000 (2)=8 (10)
1001 (2)=9 (10)
1010 (2)=10(10)
1011 (2)=11(10)
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
const int N=200200,M=2002;
LL n;
set<LL> s;
void dfs(LL u,LL ans)
{
if(u==-1)//寻找完了60位,第0位即使这个数字的最低位,再往后就没有了(查找无意义)
{
//cout<<ans<<endl;
s.insert(ans);
return ;
}
if(n>>u&1)//如果这一位是1的话,就可以有0和1两种选择
{
dfs(u-1,ans*2);
dfs(u-1,ans*2+1);
}
else dfs(u-1,ans*2);//如果当前位置是0,说明数字还在扩大,需要继续乘以2
}
int main()
{
cin.tie(0); cout.tie(0); ios::sync_with_stdio(false);
int T=1;
//cin>>T;
while(T--)
{
cin>>n;
dfs(60,0);//从最低位从右往左寻找,初始化为0
for(auto i:s)
cout<<i<<endl;
}
return 0;
}
补充一些细节的解读
dfs(3,0);//这里改成(3,0)其实就能跑完(11)10==(1011)2的所有位数,说明一开始位移的位置就站在最高位,从最高的1依次往低位转移
所以这个dfs的跑出来的数据依次是:
0
1
00
10
100
101
1010
1011
(其它的也是如此)
先从最左边的第一个1开始变换,一直跑完整个二进制长度