简体   繁体   中英

How to optimize this code for getting rid of 'time limit exceeded' problem?

I have given the problem link below. What I can't figure out is how to optimize this code so that I can make this program run within 1 sec and don't get a TLE.


Problem link: https://codeforces.com/contest/1527/problem/A


My code:

#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;
}

The recursive approach is not the most efficient (more so since an unnecessary second argument is passed), but that's certainly not the reason for the TLE. Taking each single number from x backwards can cause a lot of unneeded operations, since l & (l - 1) can yield a number well below l , and values above the result need not be taken into account; hence we can replace rett(l - 1, sum) with rett(sum, sum) and thereby limit the number of invocations to the number of set bits in x .

I think the solution they are looking for is find the highest set bit in the number, find a new number that has that bit unset and all lower bits set.

For example like this:

int foo(int x) {
    x |= x>>1;
    x |= x>>2;
    x |= x>>4;
    x |= x>>8;
    x |= x>>16;
    x >>= 1;
    return x;
}

If this makes no sense to you, you may be better off finding some other way to practice than that contest thing.

First of all, let me fix the code* you currently have (would still 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);

*by accident, the answer n is actually the first one that satisfy (n+1 & n) == 0 (which your current code does).


  1. if (x & x-1 & x-2 &... & n) == 0 then x and n-1 cannot share highest set bit

  2. and we know that the first number n that do not share the highest set bit with x (say 1xxxxx ) is the number that with all lower bits set (say 011111 )

  3. at the same time n+1 would only contain that bit (sat 10000 )

  4. which make it pretty clear that n+1 & n = 0 and x &... & n+1 & n = 0

since n is the max number possible (by 1.), we got the answer

where n = (1 << highest set bit) - 1

for how to find highest set bit you can refer to this answer , although just a guess, scan through the bits would probably sufficient

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM