这个c代码有什么问题?

时间:2016-02-02 15:51:34

标签: c algorithm integer integer-division

这是关于Codeforces的问题,link

在段[a , b]上查找 k-divisible 数字的数量。换句话说,您需要找到xa ≤ x ≤ b可以被x整除的此类整数值k的数量。

输入:
唯一一行包含三个以空格分隔的整数kab
(1≤k≤10 18 ; -10 18 ≤a≤b≤10 18

输出:
打印所需的号码。

以下是我的源代码:

#include <stdio.h>    
#include <stdlib.h>

int count(int k,int a, int b)
{
   if(a>b)
      return 0;

   if(a%k!=0)
      return count(k,a+1,b);

   return 1+count(k,a+1,b);
}

int main()
{
    int k,a,b,counter;
    scanf("%d%d%d",&k,&a,&b);

    if(k==0)
       counter=0;
    else
       counter=count(k,a,b);

    printf("%d",counter);

    return 0;
}

现在,问题在于,当我提交代码时,我收到了此回复wrong answer at test 57。所以,如果有人可以帮我弄清楚什么是错的。

2 个答案:

答案 0 :(得分:0)

我宁愿使用for循环:

for (int i = a; i < b; ++i) {
    if ((i % k) == 0) {
        printf("%d can be divided by %d\n", i, k);
        ++counter;
    }
}
printf("There are %d numbers divisible by %d between %d and %d\n", counter, k, a, b);

将输出:

-28 can be divided by 7
-21 can be divided by 7
-14 can be divided by 7
-7 can be divided by 7
0 can be divided by 7
7 can be divided by 7
14 can be divided by 7
21 can be divided by 7
28 can be divided by 7
There are 9 numbers divisible by 7 between -30 and 30

如果您输入输入:7-3030

答案 1 :(得分:0)

这是一个数学问题,真的。我们有

  

1≤≤10 18 &lt; 2 60
  -10 18 a b ≤10 18

所以我们需要inttypes.hint64_t才能描述 a b ;它也适用于 k 。要扫描这三个值,模式"%" SCNd64 " %" SCNd64 " %d" SCNd64 ""将起作用。要打印,请使用模式"%" PRId64 ""。 (包含这些文件的inttypes.h头文件在ISO C99中标准化,并且也在POSIX中定义。)

手头的实际问题是找到

的唯一整数n的数量
  

a n k b

其中 a b 是整数, k 是正整数。最小和最大的 n 履行

  

a n min k
   b n max k

也可以写成

  

a ÷ k n min
   b ÷ k n max

其中÷表示普通分裂。我们需要打印的数字是唯一的 n

的数量
  

n max - n min + 1

如果我们使用/进行整数除法(如C中所做,即截断除法),{i = ceil()(向正无穷大舍入),{{1对于 floor (向负无穷大舍入),我们记得 k 是一个正整数,我们可以把不等式写成

  

a ÷ k ≤ceil( a ÷ k )= n min
   b ÷ k ≥floor( b ÷ k )= n max

并且要打印的数字是

  

floor( b ÷ k ) - ceil( a ÷ k )+ 1

尽管标准C库在floor()中提供了函数ceil()floor(),但它们仅适用于浮点数(但即使是双精度浮点也不具有整数精度)范围-10 18 至+10 18 )。相反,我们需要使用整数舍入“技巧”:

  

ceil( x ÷ k )=( x + k - 1)/ k x &gt; 0, k &gt; 0
  ceil( x ÷ k )= x / k x ≤0, k &gt; 0
  
  floor( x ÷ k )= x / k x ≥0, k &gt; 0
  floor( x ÷ k )=( x - k + 1)/ k x &lt; 0, k &gt; 0

这里唯一的限制是我们的整数类型必须能够表示从 a - k b + k的数字,包括在内。由于math.h可以表示范围(大致)-9.22×10 18 至+ 9.22×10 18 ,因此我们得到了很好的覆盖。

对于实际的解决方案程序,您需要扫描 a b k (我已经提到了{{的正确模式1}}),验证 a b k ≥1,计算 n max n min 使用上面的数学运算,最后打印结果(再次,我提到了用于int64_t的printf模式)。如果你掌握了数学,这是非常直截了当的。