Common mistakes to be avoided in Competitive Programming in C++ | Beginners

3.6
  1. Not using of 1LL or 1ll when needed
    // A program shows problem if we
    // don't use 1ll or 1LL
    #include <iostream>
    using namespace std;
    int main()
    {
        int x = 1000000;
        int y = 1000000;
    
        // This causes overflow even
        // if z is long long int
        long long int z = x*y;
    
        cout << z;
        return 0;
    }
    
    Output: -727379968
    

    You might get some other negative value as output. So what is the problem here? The ints are not promoted to long long before multiplication, they remain ints and their product as well. Then the product is cast to long long, but we are late now as overflow has already occurred. Having one of x or y as long long should would work, as the other would be promoted. We can also use 1LL (or 1ll). LL is the suffix for long long, which is 64-bit on most C/C++ implementations. So 1LL, is a 1 of type long long.

    // C++ program to show that use of 1ll
    // fixes the problem in above code.
    #include <iostream>
    using namespace std;
    int main()
    {
        int x = 1000000;
        int y = 1000000;
    
        long long int z = 1LL*x*y;
    
        cout << z;
        return 0;
    }
    
    Output: 1000000000000
    

    Here is another place where this trick can help you.

    // Another problematic code that doesn't 
    // use 1LL or 1ll
    #include <iostream>
    using namespace std;
    
    int main()
    {
        // we should use 1LL or 1ll here
        // instead of 1. The correct statement
        // is "long long int z = 1LL << 40;"
        long long int z = 1 << 40;
        cout << z;
        return 0;
    }
    
    Output: 0
    
  2. Not using cin.ignore() with getline
    // A program that shows problem if we
    // don't use cin.ignore()
    #include <iostream>
    using namespace std;
    
    int main()
    {
        int n;
        cin >> n;
        string s;
        for(int i = 0; i<n; ++i)
        {
            getline(cin, s);
            cout << s.length() << " ";
            cout << s << endl;
        }
        return 0;
    }
    
    Input:
    4
    a b
    c d
    e f
    g h
    Output:
    0 
    3 a b
    3 c d
    3 e f
    

    So what is the problem here?
    This has little to do with the input you provided yourself but rather with the default behavior getline() exhibits. When you provided your input for the integer n (cin >> n), you not only submitted the following, but also an implicit newline was appended to the stream:

        "4\n"

    A newline is always appended to your input when you select Enter or Return when submitting from a terminal. It is also used in files for moving toward the next line. The newline is left in the buffer after the extraction into n until the next I/O operation where it is either discarded or consumed. When the flow of control reaches getline(), the newline will be discarded, but the input will cease immediately. The reason this happens is because the default functionality of this function dictates that it should (it attempts to read a line and stops when it finds a newline).

    Because this leading newline inhibits the expected functionality of your program, it follows that it must be skipped our ignored somehow. One option is to call cin.ignore() after the first extraction. It will discard the next available character so that the newline is no longer intrusive.
    cin.ignore(n, delim);
    This extracts characters from the input sequence and discards them, until either n characters have been extracted, or one compares equal to delim.

    // C++ program to show that use of cin.ignore()
    // fixes the problem in above code.
    #include <iostream>
    using namespace std;
    
    int main()
    {
        int n;
        cin >> n;
        string s;
        cin.ignore(1, '\n');
        for (int i = 0; i<n; ++i)
        {
            getline(cin, s);
            cout << s.length() << " ";
            cout << s << endl;
        }
        return 0;
    }
    
    Input:
    4
    a b
    c d
    e f
    g h
    Output:
    3 a b
    3 c d
    3 e f
    3 g h
    

    But what if we don’t know how many lines of input are going to be there? We can use this then:

    // C++ program to handle cases when we
    // don't know how many lines of input 
    // are going to be there
    #include <iostream>
    using namespace std;
    int main()
    {
        string s;
        while (getline(cin, s))
        {
            if (s.empty())
                break;
            cout << s << endl;
        }
        return 0;
    }
    
    Input:
    a b
    c d
    e f
    g h
    
    Output:
    a b
    c d
    e f
    g h
    
  3. A problem when taking remainders: In a lot of problems, you have to print your solution modulo some large prime (for example 10^9 + 7).
    // Below program shows problem if we
    // don't use don't take remainders
    // properly.
    #include <iostream>
    #define mod 1000000007
    using namespace std;
    
    int main()
    {
        long long int x, y, z;
        cin >> x >> y >> z;
        z = (z + x*y)%mod; // not good practice
        cout << z;
        return 0;
    }
    

    Since z + x*y might not fit into long long, the above code can cause problems. The better way is to do this:

    // Program to demonstrate proper
    // ways of taking remainders.
    #include <iostream>
    #define mod 1000000007
    using namespace std;
    
    int main()
    {
        long long int x, y, z;
        cin >> x >> y >> z;
    
        // good practice
        z = ((z%mod) + ((x%mod)*(y%mod))%mod) % mod;
        cout << z;
        return 0;
    }
    

    This can save you a lot Wrong Answers so it is better to take mod after every computation that might exceed long long. The test cases are generally designed to make sure you have handled overflow cases properly.
    Why does this work?
    Because (z + x*y)%mod is the same as ((z%mod) + ((x%mod)*(y%mod))%mod)%mod.

  4. cin and cout might cause TLE: In a lot of programs, the cause of TLE is generally based on your algorithm. For example, if n = 10^6 and your algorithm runs in O(n^2) then this won’t pass a 1 second Time Limit. But say, you have found an algorithm that runs in O(n) for n = 10^6. This should pass the 1 second Time Limit.
    What if this is failing?
    One possible reason is that you are using cin and cout for I/O over multiple test cases.
    You can use scanf or printf for the same. You can also use some custom Fast I/O function for the same based on something like getchar() and putchar().

    scanf and printf are faster than cin and cout. See this for more details.

    Custom Fast I/O functions:

    // C++ program to demonstrate fast input and output
    
    // use long long x = fast_input(); to read in x
    inline long long int fast_input(void)
    {
        char t;
        long long int x=0;
        long long int neg=0;
        t = getchar();
        while ((t<48 || t>57) && t!='-')
            t = getchar();
        if (t == '-') //handle negative input
        {
            neg = 1;
            t = getchar();
        }
        while (t>=48 && t<=57)
        {
            x = (x<<3) + (x<<1) + t - 48;
    
            // x<<3 means 8*x and x<<1 means 2*x so we
            // have x = 10*x+(t - 48)
            t = getchar();
        }
    
        if (neg)
            x = -x;
        return x;
    }
    
    
    // use fast_output(x, 0); to print x and a newline
    // use fast_output(x, 1); to print x and a ' ' after
    // the x
    inline void fast_output(long long int x, int mode)
    {
        char a[20];
        long long int i=0, j;
        a[0] = '0';
        if (x < 0)
        {
            putchar('-');
            x = -x;
        }
        if (x==0)
           putchar('0');
        while (x)
        {
            // convert each digit to character and
            // store in char array
            a[i++] = x%10 + 48;
            x /= 10;
        }
    
        // print each character from the array
        for (j=i-1; j>=0; j--)
            putchar(a[j]);
    
        if (mode == 0)
           putchar('\n');
        else putchar(' ');
    }
    

Related Articles :
A Better Way To Approach Competitive Programming
C++ tricks for competitive programming (for C++ 11)
Writing C/C++ code efficiently in Competitive programming

This article is contributed by Hemang Sarkar. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.

GATE CS Corner    Company Wise Coding Practice

Recommended Posts:



3.6 Average Difficulty : 3.6/5.0
Based on 18 vote(s)










Writing code in comment? Please use ide.geeksforgeeks.org, generate link and share the link here.