要不是分类真想不到这是广搜…要不是看了大神的blog我真想不到还可以这么做….
#include<iostream>
using namespace std;
int mod[600000];
int main(){
int n;
while( cin >> n){
if(!n)
return 0;
mod[1] = 1; //①
int i = 2;
while(mod[i - 1]){
mod[i] = (mod[i / 2] * 10 + i % 2) % n;
i++;
}
i--;
int num = 0;
while(i){ //②
mod[num++] = i % 2;
i /= 2;
}
while(num)
cout << mod[--num]//③
cout << endl;
}
return 0;
}
有几个点要说一下。
①这里用到了同余模定理,至于是怎么整出来的我也不知道..
(a * b) % n == ((a % n ) * (b % n)) % n
(a + b) % n == ((a % n ) + (b % n)) % n
这里是双向BFD入口,即当i分别为奇数和偶数时,分别进行BFS,
mod[i] = (mod[i / 2] * 10 + i % 2) % n;
这句话将两者结合在一起(不得不说一句太厉害了),
引用一段话
当前步 (110*10+1)%6=2
由同余模定理 (110*10+1)%6 = ((110*10)%6+1%6 )%6 = ((110%6 * 10%6)%6 +1 )%6不难发现下划线部分110%6等于 (11*10+0)%6 = 2
所以当前步(110*10+1)%6可以转变为 (2*10+1)%6=2
②是将得到的i”乘十”操作转为”模二”操作得到每一位数。
i--;
int num = 0;
while(i){
mod[num++] = i % 2;
i /= 2;
}
由于while循环最后多加了一个1,先减去。我们又可以发现将得到的这个i每次模2就是最后一位数,然后在除以2继续同样的操作便可以得到每一位。(包括最后的一个0,这个在下一步将忽略)
③
忽略了最后一位0,反向输出
最后还是要感叹一下,大神太牛了….