· Marc Lumbreras · ICPC 2026 ·
Saps C.
Aprèn C++.
6 lliçons interactives. Cada una amb teoria comparativa C vs C++, un quiz, i un exercici de codi real que s'executa al jutge. Aprens fent.
Lliçó 01
El Template ICPC
En C poses un #include per cada cosa. En C++ de competició hi ha un truc que ho canvia tot.
C clàssic
#include <stdio.h>
#include <string.h>
#include <math.h>
/* ... i molts més */
int main() {
printf("Hola!\n");
return 0;
}
C++ competició
#include <bits/stdc++.h>
using namespace std;
// Una línia = TOT inclòs
int main() {
ios::sync_with_stdio(false);
cin.tie(NULL);
cout << "Hola!\n";
return 0;
}
#include <bits/stdc++.h>Inclou absolutament totes les llibreries de C++. No cal recordar quina és on. En firmware no existeix perquè el compilador ARM no el té, però tots els jutges ICPC el suporten.
using namespace std;Sense això hauries d'escriure
std::cout, std::sort... cada vegada. En producció no és bona pràctica però en competició és universal.ios::sync_with_stdio(false) + cin.tie(NULL)Desactiva la sincronització entre cin/cout i scanf/printf. Resultat: cin/cout igual de ràpid que scanf. Posa-ho sempre i no barregi els dos sistemes.
⚠️ Un cop uses
ios::sync_with_stdio(false), no barregis scanf/printf amb cin/cout. Fes servir sempre cin/cout.🧠 Quiz
Quin és l'objectiu de
ios::sync_with_stdio(false)?A Permet barrejar scanf i cin sense problemes
B Desactiva la sincronització entre cin/cout i scanf/printf per guanyar velocitat
C Compila el codi més ràpid
D Inclou totes les llibreries
Primer programa ICPC
Escriu el template ICPC complet. El programa ha de:
1. Llegir un enter N de l'input
2. Imprimir "Hola ICPC!"
3. Imprimir el doble de N en la línia següent
1. Llegir un enter N de l'input
2. Imprimir "Hola ICPC!"
3. Imprimir el doble de N en la línia següent
Test 1⏳
Input
5
Expected
Hola ICPC!
10
Test 2⏳
Input
0
Expected
Hola ICPC!
0
Test 3⏳
Input
100
Expected
Hola ICPC!
200
solucio.cpp
⚠️ ERROR DE COMPILACIÓ
Pista 1 — Fast I/O: Posa
Pista 2 — Llegir:
Pista 3 — Imprimir:
ios::sync_with_stdio(false); cin.tie(NULL); just al principi del main.Pista 2 — Llegir:
cin >> n; llegeix un enter de l'input.Pista 3 — Imprimir:
cout << "Hola ICPC!" << "\n"; i cout << n*2 << "\n";
Lliçó 02
Input / Output
En C fas servir scanf/printf amb format strings. En C++ de competició, cin/cout és molt més còmode i, amb el fast I/O activat, igual de ràpid.
C — scanf/printf
int n;
scanf("%d", &n); // & obligatori
int a, b;
scanf("%d %d", &a, &b);
printf("%d\n", n);
printf("%d %d\n", a, b);
// Loop fins a EOF
while(scanf("%d",&n)!=EOF)
C++ — cin/cout
int n;
cin >> n; // sense &, sense format
int a, b;
cin >> a >> b; // encadenat!
cout << n << "\n";
cout << a << " " << b << "\n";
// Loop fins a EOF
while(cin >> n)
El patró més comú: T casos de prova
Patró while(t--) — Memoritza'l
int t; cin >> t; while (t--) { // t-- retorna t i després resta 1 int a, b; cin >> a >> b; cout << a + b << "\n"; }
✅ Regla d'or: Usa sempre
"\n" i no endl. endl fa flush del buffer en cada crida = desastrós amb molta sortida.🧠 Quiz
Per imprimir "Hola" en C++, quin és millor?
A cout << "Hola" << endl;
B cout << "Hola" << "\n";
C printf("Hola\n"); (usant-lo barrejat amb cin)
D print("Hola");
Suma de T casos
Llegeix T casos de prova. En cada cas, llegeix dos enters A i B i imprimeix A+B. Un resultat per línia.
Test 1⏳
Input
3
1 2
10 20
100 300
Expected
3
30
400
Test 2⏳
Input
1
999 1
Expected
1000
solucio.cpp
⚠️ ERROR DE COMPILACIÓ
Pista: Dins del while(t--), llegeix
cin >> a >> b; i imprimeix cout << a+b << "\n";Lliçó 03
Strings — Adéu char[]
C — char[]
char s[100];
scanf("%s", s);
strlen(s);
strcmp(s1,s2)==0 // comparar
strcpy(dest,src);
strcat(s1,s2);
C++ — string
string s;
cin >> s;
s.size();
s1 == s2 // comparar!
string s2 = s1;
s1 += s2;
Operacions útils a competició
string s = "hola"; s.substr(1, 2); // "ol" (pos, longitud) s.find("la"); // 2 (string::npos si no troba) reverse(s.begin(), s.end()); // invertir sort(s.begin(), s.end()); // ordenar caràcters // Recórrer caràcter a caràcter for (char c : s) { if (islower(c)) // minúscula? if (isdigit(c)) // dígit? } for (char& c : s) c = tolower(c); // tot minúscules stoi("42"); // string a int to_string(42); // int a string
🧠 Quiz
Com s'inverteix un
string s en C++?A strrev(s);
B reverse(s.begin(), s.end());
C s.reverse();
D flip(s);
Palíndrom?
Llegeix T paraules. Per a cada paraula, imprimeix "SI" si és palíndrom (igual llegit d'esquerra a dreta i de dreta a esquerra), o "NO" en cas contrari.
Test 1⏳
Input
3
radar
hola
aba
Expected
SI
NO
SI
Test 2⏳
Input
2
racecar
mundo
Expected
SI
NO
solucio.cpp
⚠️ ERROR DE COMPILACIÓ
Pista: Fes una còpia de
Llavors
s, inverteix-la amb reverse() i compara amb ==:string rev = s; reverse(rev.begin(), rev.end());Llavors
if (s == rev) cout << "SI\n"; else cout << "NO\n";
Lliçó 04
Vectors — Arrays però bons
C — array fix
int arr[100]; // mida fixa
int n = 5;
for(int i=0;i<n;i++)
scanf("%d",&arr[i]);
// No pots afegir elements
// Has de guardar la mida tu
C++ — vector dinàmic
vector<int> v; // mida dinàmica
int n; cin >> n;
for(int i=0;i<n;i++){
int x; cin >> x;
v.push_back(x);
}
v.size() // el guarda ell sol
Les 4 formes d'inicialitzar + operacions clau
// Init vector<int> v; // buit vector<int> v(n, 0); // n zeros vector<int> v(n, -1); // n valors -1 (DP!) vector<int> v = {5,3,1}; // directe // Operacions v.push_back(42); // afegir al final O(1) v.pop_back(); // eliminar l'últim O(1) v[i]; // accés O(1) v.size(); // mida O(1) // Ordenar — O(N log N) sort(v.begin(), v.end()); sort(v.begin(), v.end(), greater<int>()); // desc // Iterar for (int x : v) cout << x << " ";
⚠️ Arrays de 10⁶ elements: declara'ls global (fora del main). A l'stack dins del main pots tenir stack overflow.
🧠 Quiz
Vols un vector de N enters tots a -1. Quin codi és correcte?
A vector<int> v[n]; fill(v,-1);
B vector<int> v(n, -1);
C vector<int> v = new int[n]{-1};
D vector<int> v(n); v.fill(-1);
Ordena i imprimeix
Llegeix N enters i imprimeix-los ordenats de menor a major, separats per espais, sense espai al final.
Test 1⏳
Input
5
3 1 4 1 5
Expected
1 1 3 4 5
Test 2⏳
Input
4
9 2 7 1
Expected
1 2 7 9
Test 3⏳
Input
1
42
Expected
42
solucio.cpp
⚠️ ERROR DE COMPILACIÓ
Ordenar:
Sense espai al final:
sort(v.begin(), v.end());Sense espai al final:
for (int i = 0; i < v.size(); i++) {
if (i) cout << " ";
cout << v[i];
}
cout << "\n";
Lliçó 05
STL — Map i Set
Aquí C++ deixa C molt enrere. En C hauries d'implementar un arbre o hash table a mà. En C++ les tens gratis.
map — Diccionari clau→valor, claus ordenades, O(log n)
map<string, int> freq; freq["hola"]++; // si no existeix, crea amb 0 freq.count("hola"); // existeix? (1 o 0) // Iterar en ordre alfabètic for (auto& [key, val] : freq) cout << key << " " << val << "\n"; // unordered_map: O(1) però sense ordre unordered_map<int,int> memo;
set — Conjunt sense repeticions, ordenat, O(log n)
set<int> s; s.insert(5); s.insert(3); s.insert(5); // 5 no es duplica // s = {3, 5} s.count(5); // existeix? // Truc: eliminar duplicats d'un vector set<int> unic(v.begin(), v.end());
🧠 Quiz
Tens un vector
{3,1,4,1,5,9,2,6,5} i vols el nombre de valors únics. Codi més ràpid?A Dos bucles niats comparant tots els parells — O(n²)
B set<int> s(v.begin(), v.end()); cout << s.size();
C unique(v.begin(), v.end()); cout << v.size();
D v.unique(); cout << v.size();
Freqüències de paraules
Llegeix N paraules. Imprimeix la freqüència de cada paraula, ordenada alfabèticament. Format:
paraula frequencia per línia.Test 1⏳
Input
4
hola
mon
hola
adeu
Expected
adeu 1
hola 2
mon 1
Test 2⏳
Input
3
abc
abc
abc
Expected
abc 3
solucio.cpp
⚠️ ERROR DE COMPILACIÓ
Incrementar:
Iterar:
El map ja està ordenat alfabèticament — no cal sort addicional!
freq[w]++;Iterar:
for (auto& [key, val] : freq) cout << key << " " << val << "\n";El map ja està ordenat alfabèticament — no cal sort addicional!
Lliçó 06 — Final
Tips de Competició
Overflow — ERROR típic
int a = 1000000;
int b = 1000000;
// int max ≈ 2·10⁹
// a*b = 10¹² → OVERFLOW!
cout << a*b; // resultat incorrecte
long long — correcte
long long a = 1000000;
long long b = 1000000;
// long long max ≈ 9·10¹⁸
// a*b = 10¹² → OK!
cout << a*b; // 1000000000000
Template definitiu — Guarda'l com a snippet
#include <bits/stdc++.h> using namespace std; typedef long long ll; // ll és molt ràpid d'escriure #define all(x) (x).begin(),(x).end() int main() { ios::sync_with_stdio(false); cin.tie(NULL); int t; cin >> t; while (t--) { // la teva solució } return 0; } // sort(all(v)); ←→ sort(v.begin(),v.end())
Funcions útils ja incloses
min(3,7); // 3 max(3,7); // 7 min({5,2,8,1}); // 1 — de llista! swap(a,b); // intercanvia (sense temp variable) __gcd(12,8); // 4 — màxim comú divisor abs(-5); // 5
🧠 Quiz Final
Quin és el valor màxim que pot guardar un
int?A ~9 · 10¹⁸
B ~2.1 · 10⁹
C ~4.2 · 10⁹
D Il·limitat
Detecta i arregla l'overflow
Llegeix T casos. En cada cas, llegeix dos enters A i B (poden ser fins a 10⁹ cadascun) i imprimeix el seu producte.
⚠️ Compte: 10⁹ × 10⁹ = 10¹⁸ — no cap en un
⚠️ Compte: 10⁹ × 10⁹ = 10¹⁸ — no cap en un
int!
Test 1⏳
Input
2
1000000 1000000
3 4
Expected
1000000000000
12
Test 2⏳
Input
1
999999999 2
Expected
1999999998
solucio.cpp
⚠️ ERROR DE COMPILACIÓ
Canvia
int a, b per long long a, b. Llestos! Amb long long pots guardar fins a ~9.2·10¹⁸, molt més que 10¹⁸.