Competitive Progranning (C.P.) is a mind sport or e.sport where all the partecipants are called competitive coders and their task iis to solve a specific number of exercises within a specific time.
I am Davide Pollicino, Computer science student at the Edinburgh Napier university. My passion for competitive programming started in 2016, during the third year of Secondary High school, where I have partecipated two times to the OIS(Olimpiadi di informatica a squadre / Competitive Programming Olimpics game in Team), being part of the Hbfs team, 21st position in Italy and 2nd in Sicily
Later on, during the COVID19 lookdown, I have decided to publish my solutions write these lectures for all the future Competitive Coders and keep practicing.
Are you in Italy and you would like to start with a National competition between all the secondary high Schools? I have started from the OIS.
If you are asking yourself which one is the best platform for training, check the updated list. Every platform has a different set of exercises, a different community and a different approach to the contests and theory so, use all of them to lean as much you can.
int main(){ int main()
{
return 0; return 0;
} }
I use Visual studio Code but it does not really matter.
The most important thing is that you feel comfortable with your coding evironment, so if you are actually using something else, it's fine (as long you use at least a dark theme).
Use all of them or even more if you know other good platforms for coding practice and interview preparation.
It is useless write the same lines of code more than once, so if you can, avoid to do it. My template code for my training exercises is:
#include <bits/stdc++.h>
using namespace std;
int main() {
// To have low I/O operations time cost
ios::sync_with_stdio(0);
cin.tie(0);
// Solution
return 0;
}
Now, first line of code #include <bits/stdc++.h>, it is used usually just with gcc / g++ compilers, so if you run this line of code with other compilers, you will probably get an error. This means that during a competition you shoud just use the standard g++ libraries as:
#include <iostream>
#include <vector>
#include <utility> // Used for pairs
// And so on...
What does it do? It includes all the c++ library. In a contest is a good idea, but if you program must be particular fast and do lots of computation operation, use bits/stdc++ will makes your program a bit slower.
-
endlevery time will flush the stream so use \n could make your compilation time potentially lower. -
"\n" is faster that endl;
Sometimes, our input requires to be stored value by values, other times, we need to store all the input by line;
- Read two variables in the same line (separated by space):
int a, b;
cin >> a >> b;
- Store all the line(including spaces)
string str;
getline(cin , str);
Int is the most used data-type in CP.
if we will have to manage integers that are not in the range -210^9 and 210^9, use the type long long;
// − 9·10^18 --- 9 ·10^18
long long x = 123456789123456789LL;
Usually a long long is enough if CP. Eventually, know that there is also a 128_bit integer. In according to Stackoverflow, the 128_bit is supported by clang and g++.
#include <boost/multiprecision/cpp_int.hpp>
using namespace boost::multiprecision;
int128_t v = 1;
- typedef: give a shorter name to a datatype.
typedef long long ll;
// Use it also for more complex data types
typedef pair<int, int> pi;
ll a = 123456789; // Create and initialize a long long variable
Useful functions that you will definetely use are:
- floor() : round down to the smallest ingeter;
- ceil() : round up the biggest integer;
- trunc() : roun to smallest integer
- round() : round to the nearest integer
- setprecision() : set decimal precision
Does not matter which language you are using, make sure that you know how to convert a string to integer and an integer to string, it will be very useful.
- Int to string
int i =12;
string conversion = to_string(i); // Output: conversion = "12"
- String to int:
string s = "21";
string t = "67.456";
string u = "6746 any";
string v = "456 any684";
int conversion_1 = stoi(s); // Output: Conversion_1 = 21
int conversion_2 = stoi(t); // Output: Conversion_2 = 67
int conversion_3 = stoi(u); // Output: Conversion_3 = 6746
int conversion_4 = stoi(v); // Output: Conversion_4 = 456
A macro is a certain string in the code that will be changed before the compilation.
In c++, we create one with #define
#typedef vector<int> vi;
#define F first
#define PB push_back
// Create Vector of integers
vi list_of_numbers;
// Push back a value in my vector
list_of_numbers.PB(45);
-
Algorithm: set of step that toghether solve a problem.
-
Space complexity: how much memory does it take to wokr
-
Time complexity: how much time does it take to complete
-
Exact: Algortihm: gives an exact result
-
Approximate: try to find an anser that could be correct or partially correct (as face recognition algorithm).
- Search
- Sorting
- Computational: given one set of data calulcate another.
- Collection algorithm
GCD, Greatest common diminator: is the biggest number that can be used to divide both numbers a and b where the reminder is 0.
- Fow two integer a and b, where a > b, divide a by b;
- If the remainder, r, is 0: the GCD is b;
- Otherwise, set a to b, b to r, and repeat at step 1 until r is 0;
In O(n1 + n2) Time and O(n1 + n2) Extra Space) The idea is to use Merge function of Merge sort.
- Create an array arr3[] of size n1 + n2.
- Simultaneously traverse arr1[] and arr2[].
- Pick smaller of current elements in arr1[] and arr2[], copy this smaller element to next position in arr3[] and move ahead in arr3[] and the array whose element is picked.
// Time Complexity : O(m+n)
// Auxiliary Space : O(m+n)
int i = 0, j = 0, k = 0;
// m: size of arr1
// n: size of arr2
int arr3[m+n];
// Traverse both array
while (i<m && j <n)
{
// Check if current element of first
// array is smaller than current element
// of second array. If yes, store first
// array element and increment first array
// index. Otherwise do same with second array
if (arr1[i] < arr2[j])
arr3[k++] = arr1[i++];
else
arr3[k++] = arr2[j++];
}
// Store remaining elements of first array
while (i < m)
arr3[k++] = arr1[i++];
// Store remaining elements of second array
while (j < n)
arr3[k++] = arr2[j++];
bool is_sorted_in_increasing_order(int arr[], int n)
{
// Start to iterate from second element
for(int i =1; i < n; i++)
{
if(arr[i] < arr[i-1])
return false;
}
return true;
}
bool is_sorted_in_decreasing_order(int arr[], int n)
{
for(int i =1; i < n;i++)
{
if(arr[i] > arr[i-1])
return false;
}
return true;
}
A first approach could be merge the two arrays in a third sorted array. Once we will have the two arrays merged, we can simple store the length of the the final array (arr.size()); Now, having the length of the final final array, it can be:
- Odd: the median is the middle element. Median = arr[len/2];
- Even: the median is the average between the two middle elements. Median = (arr[len/2] + arr[len/2-1]) /2;
The first solution that I have suggested is a Naive solution: O((n1+n2) * log(n1+n2));
There is a second solution for this problem, that works in O(log(n1)), where the dimension of the first array (arr1) is smaller or equal (<=) of the second array.
//n : size of array
int largestsum(arr, n)
{
max_so_far = INT_MIN
max_ending_here = 0
for (i=0 to n-1)
{
max_ending_here += arr[i]
if max_so_far < max_ending_here :
max_so_far = max_ending_here
if max_ending_here < 0 :
max_ending_here = 0
return max_so_far
}
}
I have solved one this problem, where array given in input was sorted;
Most of the times you will not need to resize the array but just return the size of the new array that contains distinct element;
Usign Approach O(N) time and 0(N) space:
- Create a set
- Push all the elements of the sorted array in the set (just distinct ones will be inserted).
- Copy the content of the set to the array, starting from the index 0;
- Return the size of the set.
There is a second approach, where we can actually find the size of the new array with just distincts elements in O(N) time complexity and O(1) space;
int removeDuplicates(int arr[], int n)
{
// The fist element will be always part of the result
int result = 1;
for(int i =1; i < n; i++)
{
if(arr[i] != arr[result-1])
{
arr[result] = arr[i];
result++;
}
}
return result;
}
You can think, easy! I just sort the array in decreasing order!
I am sorry, all the elements that are not zeros must be in the same order of the given original array.
// Time: O(N^2)
// Space: O(1)
void moveToEnd(int arr[], int n)
{
for(int i =0; i < n; i++)
{
// Once we see a 0
if(arr[i] == 0)
{
// Search for the arr next non 0 element
for(int j=i+1; j <n; j++)
{
if(arr[j] != 0)
swap(a[i], arr[j];
}
}
}
}
void leftRotate(int arr[], int n)
{
int temp = arr[0];
for(int i=1; i< n; i++)
{
arr[i-1] = arr[i];
}
arr[n-1] = temp;
}