我的代码是用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;
}
答案 0 :(得分:1)
&#34; ......每个人类问题都有一个众所周知的解决方案 - 整洁,合理和错误。“ - H.L. Mencken
在计算机科学中我们可以改写:
&#34;对于每个计算问题,都存在简单,优雅和错误的解决方案。&#34;
hackerrank等网站上的问题,求职面试,游戏中演员的寻路,3D中的太空船队,以及任何涉及筛选数据的生产系统,都不是关于是否有解决方案。 / p>
真正的问题始终是:
&#34;找到一种方法来降低这个看似微不足道的任务的复杂度。&#34;
从a
到b
进行计数,同时将这些值组合在一起是线性时间算法 - 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);
}