如何优化此代码以摆脱“超出时间限制”问题?
Posted
技术标签:
【中文标题】如何优化此代码以摆脱“超出时间限制”问题?【英文标题】:How to optimize this code for getting rid of 'time limit exceeded' problem? 【发布时间】:2021-08-09 23:03:45 【问题描述】:我在下面给出了问题链接。我想不通的是如何优化这段代码,以便我可以让这个程序在 1 秒内运行并且不会得到 TLE。
问题链接: https://codeforces.com/contest/1527/problem/A
我的代码:
#include <bits/stdc++.h>
using namespace std;
int rett(int l, int sum)
sum = l & (l - 1);
if (sum != 0)
rett(l - 1, sum);
else
cout << (l - 1) << endl;
int main()
int t, f = 0;
int x;
cin >> t;
int i = 0;
while (i < t)
cin >> x;
int sum = 0;
rett(x, sum);
i++;
return 0;
【问题讨论】:
有什么建议吗? 你可以简单地写下每一步发生的事情,你会很快发现的。 顺便说一句,大多数 TLE(超出时间限制)问题是由于算法错误造成的。优化很少会得到低于时限的执行时间。 会调查的。 未定义行为(严重性:鼻恶魔):int rett(
但没有return
。这在 C 中可能是合法的,但在 C++ 中会发生坏事。
【参考方案1】:
首先,让我修复你当前拥有的代码*(仍然是 TLE)
void rett(int l, int sum) // void
sum = sum & (l - 1); // use sum
if (sum != 0)
rett(l - 1, sum);
else
cout << (l - 1) << endl;
// also change the invocation
rett(x, x);
*碰巧,答案n
实际上是第一个满足(n+1 & n) == 0
的答案(您当前的代码就是这样)。
如果(x & x-1 & x-2 & ... & n) == 0
那么x
和n-1
不能共享最高设置位
我们知道第一个不与x
共享最高设置位的数字n
(比如1xxxxx
)是设置了所有低位的数字(比如011111
)
同时n+1
将仅包含该位(sat 10000
)
这很清楚n+1 & n = 0
和x & ... & n+1 & n = 0
由于n
是可能的最大数量(1),我们得到了答案
在哪里n = (1 << highest set bit) - 1
关于如何找到最高设置位,您可以参考this answer,虽然只是猜测,scan through the bits 可能就足够了
【讨论】:
【参考方案2】:我认为他们正在寻找的解决方案是找到数字中设置的最高位,找到一个未设置该位且设置了所有低位的新数字。
例如这样:
int foo(int x)
x |= x>>1;
x |= x>>2;
x |= x>>4;
x |= x>>8;
x |= x>>16;
x >>= 1;
return x;
如果这对您来说没有意义,那么您最好找到其他方式来练习而不是参加比赛。
【讨论】:
【参考方案3】:递归方法不是最有效的(因为传递了不必要的第二个参数,所以更是如此),但这肯定不是 TLE 的原因。将x
中的每个数字向后取可能会导致许多不需要的操作,因为l & (l - 1)
可以产生远低于l
的数字,并且不需要考虑高于结果的值;因此我们可以将rett(l - 1, sum)
替换为rett(sum, sum)
,从而将调用次数限制为x
中设置的位数。
【讨论】:
以上是关于如何优化此代码以摆脱“超出时间限制”问题?的主要内容,如果未能解决你的问题,请参考以下文章
我需要帮助弄清楚如何将 getline 放入 presentStringPrompt 以摆脱重复代码