Online Workshops FAQ

Contents

How to read the input from a file instead from the standart input (E.g for solving first round tasks)

#include <iostream>
using namespace std;
signed main(){
    freopen("input.txt", "r", stdin); // open input.txt in read mode and redirect it to stdin
    freopen("output.txt", "w", stdout); // open output.txt in write mode and redirect to it from stdout
    int x;
    cin >> x;
    cout << x;
    return 0;
}

Make sure input.txt is in the same directory as you are running your program. If you are using the SOI-Plugin that would be your SOI-Workspace folder.

If the file is somewhere else, you can use it’s full path to open it. E.g:

freopen("C:\\Users\\Stofl\\Downloads\\myfile.txt", "r", stdin);

Note that you need to change all occurences of \ with \\ since \ is a special character in C++ strings. Doubling it results in just one backslash.

How to compute a/b floored (rounded down) and ceiled (rounded up)

a/b  // floor
(a + b-1) / b  // ceil

If you want the result not as integer but as number with digits after the comma, you need to use floats or doubles.

print(13/(double)7); // prints 1.85714

Note that floats and doubles have limited precision.

How to do fast input & output without using the soi header?

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

  // insert your code here ...
}

This is a bit more advanced: The first thing tells your program tells the program not to synchronize the c++ and the c type stream… The second one looks that your output doesn’t get flushed everytime you read something. When you print something, it actually doesn’t get printed until you flush it, write it to the actual output. But flushing is not the fastest operation so we don’t want to flush when we read something.

You don’t need this, if you use the soi-header.

At https://soi.ch/wiki/soi-header you can find more information about C++ programming without the SOI-Header

How to find out whether a number is even or odd?

print(24%2); // prints 0
print(25%2); // prints 1
print(11%7); // prints 4
print(9%3); // prints 0
print(9%4); // prints 1

The modulo operator % prints the rest of the integer division of a and b. This number is the amount by which the result was decreased when rounding down.

How do you work with text in C++

The string datatype is intended for that. Here are some examples:

print("hello");
print("Hello " + "World");
print("This is on a different line \n than this.");

What are the advantages of using vector<int> a(n) vs using int a[n]?

int a[n] is the way arrays were made in C. Since C++ is a extension of C, this works in C++ as well. You should never use it. vector is better in everything. Most notably vectors provide you with:

  • Index checking at runtime. This means, that when accessing a element outside the vector it prints that you do so, if you compile your program with the -D_GLIBCXX_DEBUG flag. The SOI Plugin does this when compiling your solution.
  • You can inintialize all fields of a vector to a arbitrary constant by writing vector<int> v(40,13);. This creates a vector of size 40 with each field initialized to the value 13.
  • There are many nice functions to work with vectors that don’t work for C-style arrays. For example sort(v.begin(),v.end()) can sort a vector. While sorting is possible for C-style arrays, other functions are missing entirely
  • The size of C++ vectors can be changed at any time. E.g with v.push_back(4) you can increase the size of the vector by 1 new field, which has the value 4.
  • C++ style vectors are needed to store the adjacency list of a graph efficiently. Without vectors one needs either to reallocate memory or very big vectors in advance, so that the graph fits regardless the specific input.

How can I print new lines if I use cout (e.g because I don’t use the SOI-Header)?

cout << 42 << "\n" << 57;

Never use endl. It is slow.

How can I sort a vector decreasingly?

sort(v.begin(),v.end(),greater<int>());
sort(v.begin(),v.end(),greater<>{});
sort(v.begin(),v.end());
reverse(v.begin(),v.end());
sort(v.begin(),v.end(),[](int const& a,int const&b){
    return a > b;
});

All of these do the same thing.

How can I initialize the elements of a vector increasingly?

vector<int> v(n);
for(int i=0;i<v.size();++i){
    v[i]=i;
}
iota(v.begin(),v.end(),0); // set the elements to 0,1,2,3....
iota(v.begin(),v.end(),20); // set the elements to 20,21,22,23....

There is no disadvantage if you use the for loop. iota uses a for loop internally as well.

Weird thing: cout << adj[a] << endl; with the error message “no operator << matches these operands”

Adj is a 2-dimensional vector. cout cannot print any kind of vectors. Just integers and strings. If you want to print vectors, you have to use the SOI-Header and use the print function or you have to write your own code to print a vector.

Is “vertex” a synonym for node?

Vertex is the correct term, but it is very common to use the term node instead. Mathematicians prefer the terms graph and vertex, while engineers prefer network and node. At SOI graph is much prefered and in many cases node will be used instead of vertex.

If I have an iterator, iter = my_vector.begin(), what do I get if I say *iter? Does that give me the index that iter points to?

*iter gives you the value in the vector where the iterator points at.

iter++ makes the iterator point to the next element in the vector.

What does expected primary-expression before '}' token mean?

It means that your program doesn’t parse correctly. This comes from the fact that somewhere in your code, what you wrote isn’t valid C++ code. Most likely you have forgotten to add a semicolon (;) . Usually on the line above where the error message is shown.

How do I terminate the execution of the program. How can I stop my program, such that it doesn’t execute the rest of the code (e.g. if some condition is true)?

Inside the main function you can just write return 0;. Anywhere else you can instantly terminate the execution of the program by calling exit(0);. This however, is almost never used in competitive programming and indicates bad code.

What condition could I use to check if all values of a bool vector are true? If not, I would like to get the index of the first false-case?

bool allTrue = true;
int firstFalse;
for(int i = 0;i<v.size();++i){
    if(!e){
        allTrue = false;
        firstFalse = i;
        break;
    }
}

or

auto result = find(v.begin(),v.end(),false);
if(result == v.end()) { // if no element is false
    print("all are true");
} else {
    print("there is at least one false one, the first is at:",distance(v.begin(),result));
}

The second one uses iterators and the find function which we didn’t teach. It’s a little bit cleaner, but it’s totally fine if you use the first one

Which one is better with regards to runtime and memory consumption?

They are exactly the same in terms of the O-notation. The actual runtime should be almost the same. If changing from one solution to the other results for you to get more points on the grader, than the testdata of the task must have been awfully terrible.

Why do you use ++i instead of i++?

It doesn’t make a difference when the statement appears isolated. In some other cases it does make a difference though.

print(i++) prints the current value of i and after the print statement the value is one bigger than before.

print(++i) first increases i and prints the now by one increased value of i.

What is the auto type?

auto tells the compiler that it should figure out the type instead of you writing it manually. You’d have to write instead of auto in the above example for finding the first false entry in the vector vector<bool>::iterator and I’m too lazy to write that. (Also note, that you can’t use auto for the argument type of a function).

How to compute the power of two numbers (integers)

Powers of 2 can be computed with:

1<<4 // computes 16
1<<8 // computes 256

To compute the power to a different basis, it’s best in most cases to write your own function. Either use a for loop or fastpow.

Do not use the pow function of the C++ Standartlibrary. It uses floating point numbers internally, which can lead to inaccurate results.

pow(base,exponent);
pow(2,4); // computes 16

How to jump to a different location in the program? How to use goto?

Never use goto. It’s a outdated feature, that is a remnant from the C days. It leads to lots of errors, which are hard to debug. And it makes it hard to understand your code even for yourself.

To jump to the end of a loop you can use break:

for(int i=0;i<20;++i){
    print(i);
    if(i==10){
        print("i has reached 10, leaving for loop");
        break;
    }
}

You can also jump to the next round of a loop with continue:

for(int i=0;i<20;++i){
    if(i==7){
        print("i has reached 7, skipping that number");
        continue;
    }
    print(i);
}

To entirely end the execution of the program you can use return 0 or exit(0) as explained in a other question.