【问题标题】:C++ divisors code with loops带循环的 C++ 除数代码
【发布时间】:2016-07-23 18:26:29
【问题描述】:

我在 coderforces 上遇到了一个名为 divisors 的问题。

我相信我已经解决了它,但它给了我一个超出时间限制错误,所以我尽我所能使它更短,但仍然是同样的错误。

在这个问题中,我必须给出这个数字应该有多少个除数。

我的代码是:

#include <iostream>
using namespace std;
int main(){
    long long  t, x;
    int res = 2;
    cin >> t;

    for (int j = 0; j < t; j++){
        cin >> x;
        for (int i = 2; i <= x / 2; i++){
            if (x%i == 0){
                res++;
            }
        }
        cout << res << endl;
    }
    return 0;
}

示例输入应该是:

3

12

7

36

输出应该是:

6

2

9

【问题讨论】:

  • 那么,您的问题究竟是什么?
  • @MohamedMoanis 我想在循环中缩短代码以避免超过时间限制,但我不知道如何
  • 那么你必须打印从 1 到 t 的每个数字有多少个除数?
  • @Polb t 是测试用例,我必须打印从 1x 有多少除数x
  • 我猜你需要看看this

标签: c++ loops


【解决方案1】:

您可以根据当前数字是奇数还是偶数,在两种不同的情况下“拆分”您的内部循环(计算当前数字的除数的循环):如果它是奇数,那么您只需检查奇数除法,从 3 开始。

无论如何,您可以通过仅检查从 2 到 floor(sqrt(x)) 的数字来进一步优化内部循环。如果一个数字x 能被i 整除,那么它也能被x / i 整除,所以检查从2 到x / 2 的数字,只看直到(int) sqrt(x)(不是绝对需要强制转换) sqrt 的结果,因为 iint)。

内部循环的代码可能如下所示:

for (int i = 2; i <= (int)sqrt(x); i++) {
    if (x % i == 0)
        res += 2;
}

【讨论】:

  • 我想我明白你在说什么,但我怎么看直到 (int) sqrt(x/2) 我不明白这个
  • 我添加了一个代码 sn-p 以使事情更清晰。
  • @MostafaIbrahem 我的错,我打错了,循环一直到sqrt(x),而不是sqrt(x / 2)(更正了)。
  • 直到(int) sqrt(x/2) 我才明白你数数的意思以及如何使用对不起我是初学者
  • 我进行了循环,直到它转到sqrt(x),但是当我输入 12时它输出 4 而不是 6 >
【解决方案2】:

首先你的代码:

#include<iostream>
using namespace std; // poluting namespace
int main(){
long long  t, x; // <------- EVIL use int64_t if that is what you want.
int res = 2; // is never reset is that your intent?
             // what if x == 1???
cin >> t;

for (int j = 0; j < t; j++){ // comparing an int32_t with an int64_t ...
    cin >> x; // stream has seldom been accused of being fast but is not likely to be the problem.

    for (int i = 2; i <= x / 2; i++){ // as already suggested stop at sqrt(x) or see below.
        if (x%i == 0){ // % is a costly operation.
            res++;
        }
    }
    cout << res << endl; // search for endl considered dangerous. use '\n' instead.
}
return 0;
}

编辑:删除了错误的代码。

所以你可以使用的是不要使用std::endl,因为它会在每次写入后刷新输出,而是使用 '\n'。

【讨论】:

  • @Surf 听不懂我用的是 G++11
  • 添加了 int64_t 的头文件。
  • @MostafaIbrahem 哪一部分有问题?
  • 给出一个输入和输出示例,以便我们知道我们要解决的问题。
  • 啊,因为这个版本给出了 1*2*2*3 或 4 个因子,所以更清楚了。
【解决方案3】:

我不认为你真的需要改进循环本身。你应该做的是利用数字的数学特性,特别是素数。您应该只循环到数字的平方根。 (见这个问题:Optimize calculation of prime numbers)。

这是我使用平方根的代码版本:

#include <cmath>
#include <iostream>

using namespace std;

int main() {
    long long inputs;
    cin >> inputs;

    for(long long j = 0 ; j < inputs ; ++j) {
        int divisors = 2;
        long long current, maxdiv;
        cin >> current;
        maxdiv = sqrt(current);

        for(long long i = 2 ; i <= maxdiv ; ++i)
            if(current % i == 0)
                divisors += 2;

        // If the square root is a divisor, we added one divisor too many above.
        if(maxdiv * maxdiv == current)
            --divisors;

        cout << divisors << "\n";
    }

    return 0;
}

【讨论】:

  • 我忘了说我还使用 "\n" 而不是 std::cout 优化了输出,以避免每次都刷新输出。
  • 没问题。如果此答案对您有用,请考虑接受。
猜你喜欢
  • 1970-01-01
  • 2015-07-20
  • 1970-01-01
  • 2015-04-26
  • 1970-01-01
  • 2018-03-06
  • 2014-09-12
  • 2012-04-17
  • 1970-01-01
相关资源
最近更新 更多