在hackerrank终止到期超时

时间:2017-10-15 05:07:44

标签: c++ algorithm timeout terminate

我的代码是用c ++编写的 目前正在尝试完成任务。链接如下

难度级别:中等

我的算法在20个测试用例中有18个正常工作。 其他2个因超时而终止。

我知道这意味着什么,但现在却没有想到提高算法的效率。

我已经在下面给出了我的代码,任何人都可以帮我解决这个问题 https://www.hackerrank.com/challenges/and-product

    #include <cmath>
    #include <cstdio>
    #include <vector>
    #include <iostream>
    #include <algorithm>
    using namespace std;

    int main() 
    {
      int t;
      unsigned long int x,y,a;
      cin>>t;
      while(t)
       {       
           cin>>x>>y;
           a=x;
              for(;x<=y;x++)
                a=a&(x);

           cout<<a<<"\n";
           t--;
       }

     return 0;
    }

1 个答案:

答案 0 :(得分:1)

  

&#34; ......每个人类问题都有一个众所周知的解决方案 - 整洁,合理和错误。“ - H.L. Mencken

在计算机科学中我们可以改写:

  

&#34;对于每个计算问题,都存在简单,优雅和错误的解决方案。&#34;

hackerrank等网站上的问题,求职面试,游戏中演员的寻路,3D中的太空船队,以及任何涉及筛选数据的生产系统,都不是关于是否有解决方案。 / p>

真正的问题始终是:

  

&#34;找到一种方法来降低这个看似微不足道的任务的复杂度。&#34;

ab进行计数,同时将这些值组合在一起是线性时间算法 - O(b-a)。当a和b接近时,这很好。但是这个问题告诉你,允许它们的间隔最多为2 ^ 32-1,大约是40亿次测试。

碰巧,这个问题可以减少到O(log2(b-a)),因为我们知道b大于a。

查看以下二进制表示的最高位:

a 01001 (9)
b 11001 (25)

有一些常见的比特如此直观地我们想象这些比特是答案中剩余1的候选者。

但是,b的位数是1,其值比a的顶部位大一个数量级。

为了从a到b计数,每个低于此顶部位的位必须存在于1和0的每个排列中 - 因为这是二进制表示的工作方式。

如果我们通过每个排列来置换二进制位域,那么最终该字段中的每个位在某一点都将包含0.这意味着将位域的每个排列进行AND运算的结果为零。

所以当我们发现b中的1位不在a中时,我们可以简单地屏蔽a中较低幅度的所有位。

现在问题变成了:

  

找到b中不存在的最高位,并屏蔽a中的所有低位。返回结果。

我们刚刚将搜索空间从0减少到了<0 N&lt; 2 ^ 32)到0&lt; N <= 32.换句话说,复杂度可以从O(N)减少到O(log2(N))。

这是一个非常有效的解决方案 - 它甚至无法优化位掩码的计算 - 它通过了对hackerrank的所有测试。

#define TESTING 0

#include <iostream>
#include <string>
#if TESTING
  #include <sstream>
#endif
#include <cstdint>

using namespace std::literals;

#if TESTING

const char test_data[] =
R"__(
3
12 15
2 3
8 13
)__";
#endif

bool has_bit(const std::uint32_t x, int bitnum)
{
    return (x & (1 << bitnum)) != 0;
}

constexpr std::uint32_t mask_here_down(int bitnum)
{
    std::uint32_t result = 0;
    while (bitnum--)
    {
        result |= std::uint32_t(1) << bitnum;
    }
    return result;
}

void algo(std::istream& in, std::ostream& out)
{
    std::uint32_t a,b;
    in >> a >> b;

    for (int bit = 32 ; bit-- ; )
    {
        if (has_bit(b, bit) and not has_bit(a, bit))
        {
            std::cout << (a & ~mask_here_down(bit)) << std::endl;
            break;
        }
    }
}

void run_tests(std::istream& in, std::ostream& out)
{
    int n;
    in >> n;

    while (n--)
    {
        algo(in, out);
    }
}

int main()
{
    #if TESTING
    auto in = std::istringstream(test_data);
    #else
    auto& in = std::cin;
    #endif

    run_tests(in, std::cout);
}