如何减少执行时间

时间:2013-10-01 15:52:28

标签: c++ algorithm time

目前,以下问题是在hackerearth.com上提供的某个测试用例执行3.008 **秒,允许时间为3.0秒,因此我得到时间限制错误。请帮助减少执行时间。

问题:     爱丽丝刚学会乘以两个整数。他想将两个整数X和Y相乘以形成数字Z.为了使问题变得有趣,他将在[1,M]范围内选择X,并在[1,N]范围内选择Y.帮助他找到数字他能做到这一点的方式。

输入

输入的第一行是测试用例T的数量。接下来是T行。每行有三个空格分隔的整数,数字Z,M和N.

输出

对于每个测试用例输出一个整数,方式的数量。

约束     1&lt; = T&lt; = 50     1&lt; = Z <= 10 ^ 12     1 <= M <= 10 ^ 12     1 <= N <= 10 ^ 12

CODE:

#include <iostream>
using namespace std;


int chk_div(long long a,long long b)
{
if(((a/b) * (b) )==a)return 1;
return 0;
}

int main()
{
   int t;
   long  i,j,count;
   long  n,m,z;
   cin>>t;
   while(t--)
   {count=0;
    cin>>z>>m>>n;
    if(m>z)m=z;
    if(n>z)n=z;
    if (m>n)m=n;
    for(i=1;i<=m;i++)
    {
         if(chk_div(z,i))count++;       
     }

   cout<<count<<"\n";
   }
return 0;
}

4 个答案:

答案 0 :(得分:8)

此处性能的主要问题是内部循环执行约10^12次迭代。你可以减少一百万次到sqrt(z) <= 10^6

这里的诀窍是注意到,当且仅当他能写z = x * y时,Alice才能写z = y * x。此外,还有x <= sqrt(z)y <= sqrt(z)。使用这些事实,您只能迭代z的平方根来计算所有情况。

答案 1 :(得分:5)

我相信这应该可以完成工作(来自@ zch的答案):

#include <iostream>
#include <cmath>

auto MAX = [] (int A, int B) -> bool { return A > B ? A : B; };
auto MIN = [] (int A, int B) -> bool { return A < B ? A : B; };

using std::cout;
using std::cin;

int main() {
    long long Z, M, N, T, low, high, temp, div;
    int ans;

    for (cin >> T; T--; ) {

        cin >> Z >> M >> N;
        temp = MIN(M, N);
        low = MIN(sqrt(Z), temp);
        high = MAX(M, N);

        for( ans = 0; low > 0 && (Z / low) <= high; --low ) {
            if ( Z % low == 0) {
                ++ans;
                div = Z / low;
                ans += (div != low && div <= temp);
            }
            //cout << temp << " * " << Z / temp << " = " << Z << "\n";
        }
        cout << ans << "\n";
    }

    return 0;
}

将稍微添加评论

带注释的代码

#include <iostream>
#include <cmath>

auto MAX = [] (int A, int B) -> bool { return A > B ? A : B; };
auto MIN = [] (int A, int B) -> bool { return A < B ? A : B; };

using std::cout;
using std::cin;

int main() {
    long long Z, M, N, T, low, high, temp, div;
    int ans;

    for (cin >> T; T--; ) {

        cin >> Z >> M >> N;
        temp = MIN(M, N);
        low = MIN(sqrt(Z), temp);//Lowest value <--We start iteration from this number
        high = MAX(M, N); //Maximum value

        for( ans = 0; low > 0 && (Z / low) <= high; --low ) {

            //Number of things going on in this for-loop
            //I will start by explaining the condition:
                //We want to keep iterating until either low is below 1
                // or when the expression (Z / low) > high.
                //Notice that as the value of low approaches 0,
                //the expression (Z / low) approaches inf
            if ( Z % low == 0) {

                //If this condition evaluates to true, we know 2 things:
                    /*Z is divisible by this value of low and 
                        low is in the range of MIN(M,N) <--true*/
                    /*Because of our condition, (Z / low) is
                        within the range of MAX(M, N) <--true*/
                ++ans;
                div = Z / low;

                //This second part checks if the opposite is true i.e.
                    /*the value of low is in the range of
                        MAX(M, N) <--true*/
                    /*the value (Z / low) is in the range of
                        MIN(M, N) <--true only in some cases*/
                ans += (div != low && div <= temp);

                //(div != low) is to avoid double counting
                /*An example of this is when Z, M, N have the values:
                    1000000, 1000000, 1000000
                    The value of low at the start is 1000 */
            }
        }
        cout << ans << "\n";
    }
    return 0;
}

答案 2 :(得分:2)

事实上,您必须以不同的方式解决问题:

找到Prime分解:

Z = A^a * B^b * ... * P^p A, B, .., P素数

所以你只需要计算a, b, ... p的可能性数量。

(因此结果最多为(1 + a) * (1 + b) * ... * (1 + p),具体取决于M&amp; N约束条件。)

答案 3 :(得分:-1)

  • 你的if(((a / b)*(b))== a)返回1;总是会返回1.为什么要将A除以B(a / b)然后将结果乘以B.这是不明确的,因为,当你说,(a / b)*(b)时你的答案是A. B`s将相互取消,你将留下A作为你的答案。所以基本上你要比较A == A,这是真的。