如何优化此代码以摆脱“超出时间限制”问题?

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 &amp; n) == 0 的答案(您当前的代码就是这样)。


    如果(x &amp; x-1 &amp; x-2 &amp; ... &amp; n) == 0 那么xn-1 不能共享最高设置位

    我们知道第一个不与x 共享最高设置位的数字n(比如1xxxxx)是设置了所有低位的数字(比如011111

    同时n+1包含该位(sat 10000

    这很清楚n+1 &amp; n = 0x &amp; ... &amp; n+1 &amp; n = 0

由于n 是可能的最大数量(1),我们得到了答案

在哪里n = (1 &lt;&lt; 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 &amp; (l - 1) 可以产生远低于l 的数字,并且不需要考虑高于结果的值;因此我们可以将rett(l - 1, sum) 替换为rett(sum, sum),从而将调用次数限制为x 中设置的位数。

【讨论】:

以上是关于如何优化此代码以摆脱“超出时间限制”问题?的主要内容,如果未能解决你的问题,请参考以下文章

如何优化此代码以运行更大的值? [复制]

如何优化此代码以仅显示圆形数组的轮廓?

C++:在优化结束时计数零

我需要帮助弄清楚如何将 getline 放入 presentStringPrompt 以摆脱重复代码

给定的两个代码之间有啥区别。一个在ideone上运行时超出时间限制,另一个工作正常[关闭]

如何添加方法或编写此代码,以免重复多次?