B. Neko Performs Cat Furrier Transform
思路:
一开始暴力就一直TLE,后来发现有规律。
eg:n = 10;
n = 1010(2)
如果是A操作,可以异或一个值x将1010的末尾的0变为1,就是
1010^1 = 1011,(这样就消去了末尾的0,离全1的二进制数进了一步)
然后是B操作,1011+1 = 1100,(这样通过将靠前的0变为1)
然后重复A操作,1100^11 = 1111(满足条件,结束)。
求10的1,11可以用x&(-x)-1求出。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<unordered_set>
using namespace std;
vector <int> vc;
unordered_set <int> st;
int main(void)
{
int n,tim = 0;
st.clear();vc.clear();
st.insert(0);
for(int i=1;i<=30;i++) st.insert((1<<i)-1);
scanf("%d",&n);
while(!st.count(n)){
if((++tim)&1){
int x = n&(-n),y = 0;
n ^= (x-1);
while(x){
x/=2;y++;
}
vc.push_back(y-1);
}
else n++;
}
printf("%d\n",tim);
int len = vc.size();
for(int i=0;i<len;i++){
if(i) printf(" ");
printf("%d",vc[i]);
}
printf("\n");
return 0;
}