xtuoj Repeat One
题目
思路
观察
全部由数码1组成的数(如1, 11, 111, 1111, …)永远不能被2或5的倍数整除。
也就是说,任何含有质因数2或5的正整数都无法整除这类数。
原因在于: 这些数总是奇数,因此不能被2整除。 这些数的个位总是1,因此不能被5整除。
如果正整数M与10互质(即M不含质因数2或5),则总存在一个由全1组成的数能被M整除。
因此,永远不能整除全1数的数就是所有2的倍数和5的倍数。
由于题目最小的由1组成的数是1,用ans表示由N个数码1组成的数,所以ans最小为1,题目求最小的N,所以我们设置ans初始值为1。
从小到大寻找ans,如果ans%M==0,即找到了最小的ans被M整除,那我们就输出ans的位数,所以我们要用一个标记记录ans的位数,这里我采用cnt,并初始化为1,因为ans初始值为1,为1位数。
如果没找到ans,那我们就要继续增加一位1,做法就是ans=ans*10+1,*10相当于向左移动了一位,+1相当于最后一位设置为1,但是我们观察样例输入输出可以看出,ans的结果可能非常大,所以这里我们采用模运算,而且我们判断ans能否被M整除。
把ans拆分为两部分,一部分是M的倍数,这部分必然能被M整除,另外一部分当然就是ans%M后的余数部分,只需要这部分能被M整除,那么整个原来的ans就能被M整除。
代码
#include<stdio.h>
#define ll long longll K,M,ans,cnt;int main(){scanf("%lld",&K);while(K--){scanf("%lld",&M);if(M%2==0||M%5==0){printf("0\n");continue;}ans=1,cnt=1;while(ans%M!=0){ans=(ans*10+1)%M;cnt++;}printf("%lld\n",cnt);}return 0;
}