如何减少此代码的运行时间并使其低于3秒。 a和b从1到10 ^ 9变化,测试用例从1到100
#include <iostream>
#include <cmath>
using namespace std;
static int testCases;
static int result[100];
int main()
{
cin>>testCases;
for (int i = 0; i < testCases; i++) {
int a, b;
cin>>a;
cin>>b;
int count = 0;
while (a <= b) {
double lim = sqrt(a);
int special = 1;
for (int z = 2; z <= lim; z++) {
if (a % (z * z) == 0) {
special = 0;
break;
}
}
if (special == 1)
count++;
a++;
}
result[i]=count;
}
for (int i = 0; i < testCases; i++)
cout<<result[i]<<"\n";
}
答案 0 :(得分:1)
虽然这个问题更适合http://codereview.stackexchange.com,但这里有一条建议......
更改此内容:
while (a <= b)
{
double lim = sqrt(a);
...
a++;
}
对此:
int lim = (int)sqrt(a);
int max = (lim+1)*(lim+1);
while (a <= b)
{
...
a++;
if (a == max)
{
lim++;
max = (lim+1)*(lim+1);
}
}
除了节省执行函数sqrt
所花费的时间之外,如果在项目设置中启用编译器优化,那么它可能能够在外部和/或内部循环上应用循环展开,因为此时在这些循环中没有其他函数调用。
另一个建议是分别对z=2
和z=3
执行测试,从那时起,仅测试z=6N-1
和z=6N+1
(即所有数字既不是2的倍数,也不是3的倍数:
while (a <= b)
{
int special = 1;
if (a%4 == 0 || a%9 == 0)
{
special = 0;
}
else for (int z=5,c=2; z<=lim; z+=c,c=6-c)
{
if (a % (z * z) == 0)
{
special = 0;
break;
}
}
...
}