【问题标题】:Hackerrank would not accept my code due to timeout, how to optimize this piece? [duplicate]Hackerrank 由于超时不接受我的代码,如何优化这块? [复制]
【发布时间】:2016-04-02 04:32:19
【问题描述】:

问题陈述是:

Watson 给 Sherlock 一个整数 NN 并问他:NN 中能被 2 整除的除数是多少?

输入格式

第一行包含 TT,即测试用例的数量。紧随其后的是 TT 行,每行包含一个整数 NN。

输出格式

对于每个测试用例,在一行中打印所需的答案。

约束

1≤T≤1001≤T≤100 
1≤N≤109

示例输入:

2\n
9\n
8

样本输出:

0\n
3

我输入了 '\n' 这意味着下一个整数将在新行中。 由于超时,Hacker Rank 不会接受我的代码。请帮我优化这段 C 代码。

我的 C 代码是:

int main() {

      int length,number,i,count =0;
      scanf("%d",&length);

      while(length--){
           scanf("%d",&number);
           for(i=2;i<=number/2;i++){
                 if(number % i == 0 && i % 2 == 0){
                   count = count + 1;
                  }
           }
           if(number % 2 == 0){
             count = count + 1;
            }
           printf("%d\n",count);
           count =0;
        }
    return 0;
}

【问题讨论】:

  • 一方面,将i 循环更改为使用i += 2 递增而不是i++。这样你就可以跳过所有奇数。然后你也可以摆脱i % 2 == 0 测试,因为你会知道它总是正确的。
  • 如果number 是奇数则不需要循环。
  • Hackerrank 上的问题叫什么名字?
  • @RajeevSingh: Here.
  • 许多在线竞赛给你一个简单的问题,对于小数据集或示例中的小数字,用蛮力解决这个问题是微不足道的。当您汇总代码时,它们会向您抛出大量数字,从而使您的蛮力方法超时。挑战在于利用数据的特性来加速解决方案。您的解决方案使用蛮力。

标签: c optimization


【解决方案1】:

下面是解决这个问题的算法:

如果是偶数:
i=2 运行循环直到数字的平方根,即:sqrt(number) 并在以下两种情况下增加 count if i 除数(number%i==0)

  • 如果 i 是偶数(i%2==0)

  • for q where q=number/i if i 不等于 q(i!=q) q 是偶数(q%2==0),因为如果 i 除数,则表示 q 也会除(number/q=i)

最后将计数增加 1,因为数字也会除自身。

如果数字是奇数:
count 将为 0,因为没有 i(even) 会除以奇数。

int main() 
{
  int length,number,i,count;
  scanf("%d",&length);

  while(length--)
  {
      scanf("%d",&number);
      count =0;i=2;
      if(number%2==0)
      {
          while(i*i<=number)
          {
              if(number%i==0)
              {
                  if(i%2==0)
                      count++;
                  int q=number / i;
                  if (i !=q && q%2==0)
                      count++;
              }
              i++;
          }
          count++;
      }
      printf("%d\n",count);
  }
  return 0;
}

【讨论】:

  • sqrt 是一个浮点数,可能存在舍入问题;也许i*i &lt; n 是一个更好的条件。您可以通过首先在内部 while 循环中测试 number % i == 0 来进一步优化这一点,然后仅当 i 是除数时才计算 q。在这种情况下,number % q == 0 保证为真,您可以跳过此测试。
  • 感谢优化,现在缩短了 0.01 秒 :)
  • 嗯,收益取决于之前花了多少。通过测试中的优化,我可以将执行时间缩短一半。 (不过,我已经对 100 多个数字进行了测试。)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-08
  • 2023-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多