求至少多少个1组成的数能被2013整除,代码如下

qq_40724282 2018-12-09 03:36:29

为什么一直得不到输出?
...全文
1391 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
就冲你敲这么多字,也应该直接零分~~~
ShanTUT 2019-01-29
  • 打赏
  • 举报
回复 2
这个题目很麻烦,楼主的做法一上来就是错的。 你的value是int类型,在win32环境下,一个int能表示的最大的数只有21亿,用十进制表示就是一个十位数。 也就是说在你的for循环里,当i>10以后,就会数据溢出。所以这么找,肯定找不到正确答案。 我的思路是这样:首先把2013分解质因数:2013=3*11*61。 也就是说我们的目标结果,必须同时是3、11、61这三个质数的整数倍。 (1)要保证是3的整数倍,需要结果的数位数是3的整倍数。 (2)要保证是11的整数倍,需要结果的数位数是2的整倍数。 综合(1)、(2)两点,我们需要结果数位数是6的整倍数。 接下来也是最复杂的,我们需要找到多少个由1组成的数,才能是61的整倍数。 前面说过,int最大能表示到21亿,我用计算器算了下,在这个范围内还是没有找到由1组成且为61的整倍数的数。我们还需要做一些数学运算。 我们假设a除以x商的整数部分是m,余数是n(a、x、m、n都是正整数,且n<x) b除以x商的整数部分是k,余数是l(b、k、l都是正整数,且l<x) 那么a=mx+n,b=kx+l。 (a+b) mod x (mod表示取余运算,相当于C++的%) =[(m+k)x+(n+l)] mod x =(n+l) mod x (因为(m+k)x这一项包含因子x,所以如果产生余数也只是(n+l) mod x 这一项出现余数) 同理(a·b) mod x = (n·l) mod x。 所以我们可以得出两条结论: 两数之和(或乘积)对第三个数去余数,就是把前两个数对第三个数分别取余,然后把余数加和(或相乘)后再对第三个数取余数。 这个结论对于数据溢出的取余运算非常有帮助。 除此之外,解这个题目还需要用到抽屉定理:对于任意(n+1)个整数,其中必定存在至少两个,它们对n取余的结果是相同的(n是正整数)。 在我们这个题目里就是:对于1、11、111、1111、11111、......、111...11(62个1),这62个不相等的、且是由若干1组成的正整数、其中必定存在两个,对61取余数是结果相同的。那么这两个整数之差,必定是61的整倍数。 假设这两个整数分别是第i个和第j个(i>j)。 i个1 - j个1 = 1111...111000...00(i-j个1、j个0) =10^j * 111...111(i-j个1) 由于 ( i个1 - j个1 ) mod 61 = 0。 而10^j 不包含因子61,那么111...111(i-j个1)必定是61的整倍数。 而(0≤j<i≤62),所以写程序时候,只需要找62次就可以。 具体代码是这样的: int arr1[62] = { 0 }; /* arr1的第i项,表示10^i对61的余数。 即arr[0]=1%61 = 1; arr[1] = 10 % 61 = (arr[0] * 10) % 61 =10; arr[2] = 100 % 61 = (arr[1] * 10) % 61 =39; arr[3] = 1000 % 61 = (arr[2] * 10) % 61 = 24; ...后面的代码楼主自己写,总之大概就是这么个思路。 */ 接下来还需要第二个数组: int arr2[62] = { 0 }; /* arr2的第i项,表示111...111(i个1)^i对61的余数。 arr2[0] = 1 % 61 = (arr1[0]) % 61 = 1; arr2[1] = 11 % 61 = (arr1[0] + arr1[1]) % 61 = 11; arr2[2] = 111 % 61 = (arr1[0] + arr1[1] + arr1[2]) %61 = 50; arr2[3] = 1111 % 61 = (arr1[0] + arr1[1] + arr1[2] + arr1[3]) % 61 = 13; ...后面的代码楼主还是自己去写,逻辑也基本上就是这样了 */ 再然后,在arr2这个数组里找到任意两个相同的项就可以了。 arr2中相同项的下标之差个1,就是61的整倍数。 最后,别忘了这个题目要求算的结果:是2013的整倍数,而非61的整倍数。 之前说过,我们需要结果数位数是6的整倍数。所以算完了下标之差,还需要和6取一下最小公倍数,才是最后结果。 纯手打,求给分
636f6c696e 2019-01-29
  • 打赏
  • 举报
回复
想复杂了,没有用程序的方法去思考,但是你指出了一个楼上没指出的问题,楼主这样的算法就算value放在外面,int类型也会溢出。 因此还需要在每次循环结束后加一句value = value % 2013;
引用 14 楼 ShanTUT 的回复:
这个题目很麻烦,楼主的做法一上来就是错的。 你的value是int类型,在win32环境下,一个int能表示的最大的数只有21亿,用十进制表示就是一个十位数。 也就是说在你的for循环里,当i>10以后,就会数据溢出。所以这么找,肯定找不到正确答案。 我的思路是这样:首先把2013分解质因数:2013=3*11*61。 也就是说我们的目标结果,必须同时是3、11、61这三个质数的整数倍。 (1)要保证是3的整数倍,需要结果的数位数是3的整倍数。 (2)要保证是11的整数倍,需要结果的数位数是2的整倍数。 综合(1)、(2)两点,我们需要结果数位数是6的整倍数。 接下来也是最复杂的,我们需要找到多少个由1组成的数,才能是61的整倍数。 前面说过,int最大能表示到21亿,我用计算器算了下,在这个范围内还是没有找到由1组成且为61的整倍数的数。我们还需要做一些数学运算。 我们假设a除以x商的整数部分是m,余数是n(a、x、m、n都是正整数,且n<x) b除以x商的整数部分是k,余数是l(b、k、l都是正整数,且l<x) 那么a=mx+n,b=kx+l。 (a+b) mod x (mod表示取余运算,相当于C++的%) =[(m+k)x+(n+l)] mod x =(n+l) mod x (因为(m+k)x这一项包含因子x,所以如果产生余数也只是(n+l) mod x 这一项出现余数) 同理(a·b) mod x = (n·l) mod x。 所以我们可以得出两条结论: 两数之和(或乘积)对第三个数去余数,就是把前两个数对第三个数分别取余,然后把余数加和(或相乘)后再对第三个数取余数。 这个结论对于数据溢出的取余运算非常有帮助。 除此之外,解这个题目还需要用到抽屉定理:对于任意(n+1)个整数,其中必定存在至少两个,它们对n取余的结果是相同的(n是正整数)。 在我们这个题目里就是:对于1、11、111、1111、11111、......、111...11(62个1),这62个不相等的、且是由若干1组成的正整数、其中必定存在两个,对61取余数是结果相同的。那么这两个整数之差,必定是61的整倍数。 假设这两个整数分别是第i个和第j个(i>j)。 i个1 - j个1 = 1111...111000...00(i-j个1、j个0) =10^j * 111...111(i-j个1) 由于 ( i个1 - j个1 ) mod 61 = 0。 而10^j 不包含因子61,那么111...111(i-j个1)必定是61的整倍数。 而(0≤j<i≤62),所以写程序时候,只需要找62次就可以。 具体代码是这样的: int arr1[62] = { 0 }; /* arr1的第i项,表示10^i对61的余数。 即arr[0]=1%61 = 1; arr[1] = 10 % 61 = (arr[0] * 10) % 61 =10; arr[2] = 100 % 61 = (arr[1] * 10) % 61 =39; arr[3] = 1000 % 61 = (arr[2] * 10) % 61 = 24; ...后面的代码楼主自己写,总之大概就是这么个思路。 */ 接下来还需要第二个数组: int arr2[62] = { 0 }; /* arr2的第i项,表示111...111(i个1)^i对61的余数。 arr2[0] = 1 % 61 = (arr1[0]) % 61 = 1; arr2[1] = 11 % 61 = (arr1[0] + arr1[1]) % 61 = 11; arr2[2] = 111 % 61 = (arr1[0] + arr1[1] + arr1[2]) %61 = 50; arr2[3] = 1111 % 61 = (arr1[0] + arr1[1] + arr1[2] + arr1[3]) % 61 = 13; ...后面的代码楼主还是自己去写,逻辑也基本上就是这样了 */ 再然后,在arr2这个数组里找到任意两个相同的项就可以了。 arr2中相同项的下标之差个1,就是61的整倍数。 最后,别忘了这个题目要求算的结果:是2013的整倍数,而非61的整倍数。 之前说过,我们需要结果数位数是6的整倍数。所以算完了下标之差,还需要和6取一下最小公倍数,才是最后结果。 纯手打,求给分
Curry____30 2019-01-29
  • 打赏
  • 举报
回复
把value的初始化放到循环外面。
「已注销」 2019-01-23
  • 打赏
  • 举报
回复
这么小的数据内误解 解为 60*n 个1,n>=1
weixin_42319400 2019-01-23
  • 打赏
  • 举报
回复
循环开始后,第一行代码就把VALUE=0了,所以一直是0%2013,才不会有结果
AlbertS 2019-01-21
  • 打赏
  • 举报
回复
作用域错误吧,把`int value =0;`放到循环外边
香蜜凉凉 2019-01-21
  • 打赏
  • 举报
回复
把‘int value=0’放在循环外
扛刀仔 2019-01-19
  • 打赏
  • 举报
回复
int sd=0*10 + 1; 输出没值
扛刀仔 2019-01-19
  • 打赏
  • 举报
回复


代码把它 value=value*10+1; 当成字符串拼接处理了
weixin_44345472 2019-01-18
  • 打赏
  • 举报
回复
这个问题我也遇到过,是因为你把int value=0;写到这个loop里面了 所以导致每运行一次,这个valu这个值会重新变成0;只要把这个东西放在外面就行了。
@风轻云淡_ 2018-12-10
  • 打赏
  • 举报
回复
在 int value =0 前面 加上 static , 好处就是保留上一次的值同时,限定了变量的作用域;当然了,二楼是最常见的做法。
636f6c696e 2018-12-10
  • 打赏
  • 举报
回复
每次循环value的值都是1
  • 打赏
  • 举报
回复 1
for (int i = 1, j = 1; ; i = i * 10 + 1, j++)
if (!(i %= 2013)) {printf("%d\n", j); break;}
自信男孩 2018-12-10
  • 打赏
  • 举报
回复
把int value = 0;放到for循环外,且是循环之前;即在进入main循环之后就定义value;放到循环中,相当于每次循环都会先执行一次value = 0;
得到的value自然是固定的。一次不会有输出
weixin_42359982 2018-12-10
  • 打赏
  • 举报
回复
每次循环的一开始你就把value值变为0了,当然没用了。你要把 int value = 0; 放到for循环前面:int value = 0;for(; ;){}
keysec 2018-12-09
  • 打赏
  • 举报
回复
把int value =0弄到for循环体的外面

33,311

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 新手乐园
社区管理员
  • 新手乐园社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧