-1

I have used a normal if-elseif ladder to update some variables depending upon conditions. The condition can be either a, b or c. That's why I am using an if-elseif ladder.

But, when I use the if-elseif ladder without the curly braces, I'm not getting the required output. It's as if the code flows into the first if only, and if the condition is false, it's not going into the other else-if's. As far as I know, the default scope of the if block is 1 line below it, right? So, even if I refrain from using curly braces, it should work normally as I'm expecting it to, right?

If I use curly braces, I'm getting the desired output.

#include <iostream>
#define int long long
#define endl "\n"
using namespace std;

signed main(){
    ios_base::sync_with_stdio(false); cin.tie(NULL);

    int t; cin >> t;
    int n;

    while (t--){
        cin >> n;
        int min_counter_11 = 1e10;
        int min_counter_10 = 1e10;
        int min_counter_01 = 1e10;
        while(n--){
            int m;
            string s;

            cin >> m >> s;

            if (s == "11")
                if (m < min_counter_11)
                    min_counter_11 = m;
            else if (s == "10")
                if (m < min_counter_10)
                    min_counter_10 = m;
            else if (s == "01")
                if (m < min_counter_01)
                    min_counter_01 = m;
        }
        int res = min(min_counter_01 + min_counter_10,min_counter_11);

        if (res > 1e9)
            cout << -1 << endl;
        else
            cout << res << endl;
    }
}
  • What does this #define int long long mean?! – Vlad from Moscow May 08 '23 at 20:19
  • This is a case of *dangling else*. The `else` don't match the `if` that you think they do. For example the first `else` is paired with the second `if`, not the first as your indentation assumes. – john May 08 '23 at 20:20
  • 2
    Your indentation shows that you don't know which `if` your `else`s are matching. This is why braces are useful. – Drew Dormann May 08 '23 at 20:20
  • 2
    C++ does not care about indentation. `else` gets "attached" to the `if` that immediately precedes it – NathanOliver May 08 '23 at 20:21
  • 1
    `#define int long long` `#define endl "\n"` -- What?? An `int` and `long long` are standard C++ types, do not do this. Then `endl` and `\n` are two different things. Then this: `signed main` -- why? The `main` function is `int main()`. Stop using "competitive coding" sites to learn C++, as all it does is teach you how to write bad code, if not code that isn't legal. – PaulMcKenzie May 08 '23 at 20:30
  • Use curly brackets then, it not only solves the issue you are seeing, but also makes the intent clear. – user20716902 May 08 '23 at 20:32
  • @VladfromMoscow -- It is cargo cult programming, brought to you by those competitive competition websites. – PaulMcKenzie May 08 '23 at 20:36
  • @PaulMcKenzie I'm aware int and long long are complete different datatypes in C++. And the difference between endl and \n. This definitions I've used are solely for Competitive Programming (CP) events, please don't criticize me for that! I've define int as long long so that I don't have to hunt for constraints again and again in CP events and choose which datatype to go with. I conveniently use int (going by that definition). And I've got a habit of using endl, but apparently it increases the runtime than '\n'. So to cure my laziness, I have used that definition as well. – ppl_call_me_tima May 08 '23 at 20:36
  • 1
    @ppl_call_me_tima `#define int long long`. Instead of doing stuff like this, just use `int64_t` instead of `long long` if your goal was truly to do things quickly. And remember, we have to *look* at your code, and maybe even compile and run it. Obfuscating it with nonsense like this just makes the job much more difficult for those willing to help. – PaulMcKenzie May 08 '23 at 20:37
  • @PaulMcKenzie I'm sorry, I'll be careful next time. And thanks for the advice. – ppl_call_me_tima May 08 '23 at 20:40
  • @ppl_call_me_tima -- No problem. If you did the `int64_t`, that would have cleared up at least two coding issues, the `#define` wouldn't be necessary, and then you wouldn't have to be forced to use `signed main()` but instead, standard `int main()`. – PaulMcKenzie May 08 '23 at 20:43
  • @PaulMcKenzie Yeah I realized that solving problems risen from creating disturbing shortcuts is unnecessary, but I'm not well acquainted with alternatives such as using int64_t , but yes that will solve 1 original problem, and 1 problem born in attempt to solve that problem. So thanks once again! – ppl_call_me_tima May 08 '23 at 20:49

3 Answers3

4

For starters, this directive:

#define int long long

does not make any sense.

Also, you need to include the <string> header:

#include <string>

As for your question, these if statements:

if (s == "11")
    if (m < min_counter_11)
        min_counter_11 = m;
else if (s == "10")
    if (m < min_counter_10)
        min_counter_10 = m;
else if (s == "01")
    if (m < min_counter_01)
        min_counter_01 = m;

are actually equivalent to:

if (s == "11")
    if (m < min_counter_11)
        min_counter_11 = m;
    else if (s == "10")
        if (m < min_counter_10)
            min_counter_10 = m;
        else if (s == "01")
            if (m < min_counter_01)
                min_counter_01 = m;

That is, the else part belongs to the closest if statement, and that has nothing with the scope of the if statement, or the way you indent your code (unlike in Python, for example).

You should rewrite the if statements the following way, using curly bracs around compound statements:

if (s == "11")
{
    if (m < min_counter_11)
        min_counter_11 = m;
}
else if (s == "10")
{
    if (m < min_counter_10)
        min_counter_10 = m;
}
else if (s == "01")
{
    if (m < min_counter_01)
        min_counter_01 = m;
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • Thanks a lot for the answer! I'd like to apologize for the scary definitions I've made in my code like defining int as long long. Pardon me for that, it's just a a little shortcut for not having to look for constraints every time and use int / long long accordingly in Competitive Coding events. Also the header includes all the header files such as . And I'm aware that it's inefficient and increases compile time... But as long as it's not affecting the runtime, it's appreciated in Competitive Programming only I guess. – ppl_call_me_tima May 08 '23 at 20:31
  • `#define int long long` not only _doesn't make sense_, it's Undefined Behavior. It trashes your entire program. – Drew Dormann May 08 '23 at 20:33
  • Don't use `#define` to create new types, use `typedef` (ie `typedef long long ll_int;`) or `using` (ie `using ll_int = long long;`), and then you can use `ll_int` instead of `int` where needed – Remy Lebeau May 08 '23 at 20:34
  • @ppl_call_me_tima, *competitive programming* is **trash**. You must learn efficient programming. All the bugs and vulnerable software around come from this wrong mindset. – Red.Wave May 09 '23 at 10:02
3

Your code:

if (s == "11")
    if (m < min_counter_11)
        min_counter_11 = m;
else if (s == "10")
    if (m < min_counter_10)
        min_counter_10 = m;
else if (s == "01")
    if (m < min_counter_01)
        min_counter_01 = m;

is equivalent to the more accurately indented:

if (s == "11")
    if (m < min_counter_11)
        min_counter_11 = m;
    else if (s == "10")
        if (m < min_counter_10)
            min_counter_10 = m;
        else if (s == "01")
            if (m < min_counter_01)
                min_counter_01 = m;

C++ does not change your logic based on your indentation.

Drew Dormann
  • 59,987
  • 13
  • 123
  • 180
0

My compiler gives the following warnings for your code:

scratch/src/s13.cpp:32:13: warning: add explicit
      braces to avoid dangling else [-Wdangling-else]
            else if (s == "01")
            ^
scratch/src/s13.cpp:29:13: warning: add explicit
      braces to avoid dangling else [-Wdangling-else]
            else if (s == "10")
            ^

As mentioned in the comments, the indentation does not match how the statements are paired.

RandomBits
  • 4,194
  • 1
  • 17
  • 30