《编程之美》2.8 找符合条件的整数。
任意给定一个正整数N,求一个最小的正整数M(M>1),使得N*M的十进制表示形式里只含有1和0。
作者经过对问题的分析,把计算两个数相乘结果转变成了对余数信息的处理。通过算法思想的转换简化了问题的处理过程,并在处理余数的过程中,把中间过程的余数信息保存下来,这也避免了大量的浪费效率的模运算。同时,由于所要求的结果可能很大,我们采用bit位图的方式,用在相应bit位为1标志十进制为有值,可以扩展程序可以处理的范围。
#include <stdio.h>
int iRes[100]; /* bitmap */
int OneAndZeroNum(int N)
{
int i, X; /* X记录目前遍历的十进制位数 */
int num; /* num = 10^X */
for(i = 0; i < N; i++)
iRes[i] = 0;
for(X = 0, num = 1; ; X++, num *= 10)
{
int tempRes = num % N;
if(tempRes != 0) /* 如果10^X不能整除N */
{
if(iRes[tempRes] == 0)
iRes[tempRes] = 1 << X; /* 记录为tempRes时,十进制数的位数 */
for(i = 1; i < N; i++) /* 更新余数对应的十进制数 */
if(iRes[i] != 0 && iRes[(i+tempRes)%N] == 0 && \
((iRes[i] & (1 << X)) == 0)) /* 避免错误重复更新 */
iRes[(i+tempRes)%N] |= (iRes[i] | (1 << X));
if(iRes[0] != 0)
return iRes[0];
}
else
{
iRes[0] = 0;
iRes[0] |= 1 << X;
return iRes[0];
}
}
return 0;
}
int main()
{
int N;
int iBitMapNum, iFactor;
int Num;
while(1)
{
scanf("%d", &N);
iBitMapNum = OneAndZeroNum(N);
iFactor = 1;
Num = 0;
while(iBitMapNum)
{
Num += (iBitMapNum & 0x01) * iFactor;
iFactor *= 10;
iBitMapNum >>= 1;
}
printf("%d\n", Num);
}
return 0;
}