我是竞争性编码(C ++)的新手,并且正在实施基于实施的hackerEarth问题。我提交了一个问题来查找3 diff中数组的求和。部分 。 这是我的代码执行1.010039s:
int main()
{
long unsigned int n, a[100000], s1 = 0, s2 = 0, s3 = 0;
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
if (i % 3 == 0)
s3 = s3 + a[i];
else if ((i - 2) % 3 == 0)
s2 = s2 + a[i];
else
s1 = s1 + a[i];
}
cout << s1 << " " << s2 << " " << s3;
return 0;
}
这里是最少时间代码:
int main()
{
int n;
long unsigned int a[100000];
long unsigned int s1 = 0, s2 = 0, s3 = 0;
int i;
cin >> n;
for (i = 0; i < n; i++) {
cin >> a[i];
}
for (i = 0; i < n; i = i + 3) {
s1 = s1 + a[i];
}
for (i = 1; i < n; i = i + 3) {
s2 = s2 + a[i];
}
for (i = 2; i < n; i = i + 3) {
s3 = s3 + a[i];
}
cout << s1 << " " << s2 << " " << s3 << endl;
return 0;
}
我们可以看到,在第二种情况下,循环还有更多,但为什么它更快?
答案 0 :(得分:0)
只要它们不重叠,你写的循环数并不重要。
使第二个算法更快的真正因素是每次索引i
移动3次而不是第一个算法(逐步),你也可以考虑if
s正如您所知,在竞争性节目中每毫秒计数的巨大数据输入的变化
因为我会建议你学习复杂性,这将有助于你对我的竞争激情。
答案 1 :(得分:0)
最少时间的代码是非分支的(循环条件除外)。这意味着编译器确切地知道将会发生什么,将执行哪个指令。这也意味着CPU知道即将到来的指令以及将执行的指令。这样就可以由编译器生成最佳指令,并允许CPU提取合适的内存并为即将发生的事情做好准备。 结果,整个CPU大部分时间都得到了充分利用。
在您的情况下,无法预测i%3的结果,因此CPU停顿了,因为它并不总是正确地计划ifs的哪个分支。实际上,您的代码对于缓存局部性更好,因为它只接触一次连续内存。但是,分支部分会带来更大的性能损失。
一般规则:代码中的if最少,则速度可能更快。