这里所谓的“光棍”,并不是指单身汪啦~ 说的是全部由1组成的数字,比如1、11、111、1111等。传说任何一个光棍都能被一个不以5结尾的奇数整除。比如,111111就可以被13整除。 现在,你的程序要读入一个整数x
,这个整数一定是奇数并且不以5结尾。然后,经过计算,输出两个数字:第一个数字s
,表示x
乘以s
是一个光棍,第二个数字n
是这个光棍的位数。这样的解当然不是唯一的,题目要求你输出最小的解。
提示:一个显然的办法是逐渐增加光棍的位数,直到可以整除x
为止。但难点在于,s
可能是个非常大的数 —— 比如,程序输入31,那么就输出3584229390681和15,因为31乘以3584229390681的结果是111111111111111,一共15个1。
输入格式:
输入在一行中给出一个不以5结尾的正奇数x
(<1000)。
输出格式:
在一行中输出相应的最小的s
和n
,其间以1个空格分隔。
输入样例:
31
结尾无空行
输出样例:
3584229390681 15
整体思路:
显然这里按照传统的大数除法是行不通的,存储空间不够,数据过大也会产生精度丢失,只能另辟捷径了。
在传统的除法之中,比如144 / 6 ,先判断 1 < 6 ,无法用1除,改用14(14=1*10+4)除,14 / 6 = 2(整数除法),余数为2(不为0,继续进行操作),
继续用2*10+4=24,24除以6,商为4,余数为0结束操作。
可以巧妙地采用模拟除法,被除数s(s不是固定为某个值,初始值为第一位数,本题为1),除数x,余数为y。第一步先判断s是否大于等于x,满足则开始相除,
不满足则s = s * 10 +1直至s >= x(这里的1为第二位数,仅仅是本题为1)然后取余,y = s / x;利用整数除法得出第一位数s / x;类比传统除法,此时的
s = s * 10 + 1;然后判断y是否为0,为0则结束操作,否则继续循环。
整体代码:
#include <stdio.h> int main (void){ int x = 0,y = 1; int s = 1; int count = 1; scanf ("%d",&x); while(s < x) { s = s * 10 + 1; count++; } while (y != 0) { y = s % x; printf("%d",s / x); s = y * 10 + 1; count++; } printf(" %d",count - 1); return 0; }
讨论:
- y=0后到结束循环之前,count多加了一次,所以最后输出时要减一,也可以在输出s/x后面加上判断语句跳出循环
- 模拟除法非常巧妙,与数组结合可以运算非常大的数。