Ciclo For
Domina el ciclo for para repetir instrucciones de forma controlada
¿Por qué necesitamos ciclos?
Imagina que quieres imprimir los números del 1 al 100. Sin ciclos, tendrías que escribir 100 líneas de cout. ¿Y si fueran un millón? Imposible.
Los ciclos (o loops) permiten que tu programa repita un bloque de código muchas veces sin tener que escribirlo múltiples veces. Es como decirle a alguien: "Repite esto 100 veces" en lugar de darle la misma instrucción 100 veces.
El ciclo for
El for es el ciclo más usado en programación competitiva. Es perfecto cuando sabes cuántas veces quieres repetir algo.
for (inicialización; condición; actualización) {
// Código que se repite
}
Ejemplo básico:
for (int i = 1; i <= 5; i++) {
cout << i << endl;
}
Salida:
1
2
3
4
5
Las tres partes del for
Desglosemos for (int i = 1; i <= 5; i++):
-
Inicialización (
int i = 1): Se ejecuta una sola vez al inicio. Aquí creamos nuestra variable contadoraiy le damos su valor inicial. -
Condición (
i <= 5): Se verifica antes de cada repetición. Si es verdadera, se ejecuta el cuerpo. Si es falsa, el ciclo termina. -
Actualización (
i++): Se ejecuta después de cada repetición. Normalmente incrementa o decrementa el contador.
Flujo paso a paso:
1. i = 1 (inicialización)
2. ¿i <= 5? Sí (condición) → ejecuta el cuerpo → imprime 1
3. i++ → i = 2 (actualización)
4. ¿i <= 5? Sí → ejecuta el cuerpo → imprime 2
5. i++ → i = 3
6. ¿i <= 5? Sí → ejecuta el cuerpo → imprime 3
7. i++ → i = 4
8. ¿i <= 5? Sí → ejecuta el cuerpo → imprime 4
9. i++ → i = 5
10. ¿i <= 5? Sí → ejecuta el cuerpo → imprime 5
11. i++ → i = 6
12. ¿i <= 5? No → FIN del ciclo
Analogía: Piensa en dar vueltas a una pista de atletismo. La inicialización es ponerte en la línea de salida. La condición es "¿ya di las vueltas necesarias?". La actualización es contar una vuelta más.
Variaciones del for
Contar hacia atrás
for (int i = 10; i >= 1; i--) {
cout << i << " ";
}
// Salida: 10 9 8 7 6 5 4 3 2 1
Avanzar de 2 en 2
for (int i = 0; i <= 10; i += 2) {
cout << i << " ";
}
// Salida: 0 2 4 6 8 10
Empezar desde 0 (lo más común en programación)
En programación, es convención empezar a contar desde 0:
for (int i = 0; i < 5; i++) {
cout << i << " ";
}
// Salida: 0 1 2 3 4 (5 números: del 0 al 4)
La forma más estándar de repetir algo N veces es: for (int i = 0; i < n; i++). Esto da exactamente n iteraciones con i tomando valores de 0 a n-1. Te acostumbrarás rápidamente a esta notación.
Recorrer un arreglo
int arr[] = {10, 20, 30, 40, 50};
int n = 5;
for (int i = 0; i < n; i++) {
cout << "arr[" << i << "] = " << arr[i] << endl;
}
// arr[0] = 10
// arr[1] = 20
// arr[2] = 30
// arr[3] = 40
// arr[4] = 50
For-each (basado en rango)
C++ moderno tiene una forma más elegante de recorrer colecciones:
vector<int> v = {10, 20, 30, 40, 50};
for (int x : v) {
cout << x << " ";
}
// Salida: 10 20 30 40 50
Se lee como "para cada x en v". Es más limpio cuando no necesitas el índice.
Ciclos anidados
Puedes poner un ciclo dentro de otro:
for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 3; j++) {
cout << "(" << i << "," << j << ") ";
}
cout << endl;
}
Salida:
(1,1) (1,2) (1,3)
(2,1) (2,2) (2,3)
(3,1) (3,2) (3,3)
Analogía: Piensa en un reloj. La manecilla de los minutos (ciclo interno j) da una vuelta completa por cada movimiento de la manecilla de las horas (ciclo externo i).
Tabla de multiplicar
int n;
cin >> n;
for (int i = 1; i <= 10; i++) {
cout << n << " x " << i << " = " << n * i << endl;
}
Entrada: 7
Salida:
7 x 1 = 7
7 x 2 = 14
7 x 3 = 21
...
7 x 10 = 70
Patrón de triángulo
int n = 5;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= i; j++) {
cout << "* ";
}
cout << endl;
}
Salida:
*
* *
* * *
* * * *
* * * * *
break y continue
break: salir del ciclo inmediatamente
for (int i = 1; i <= 100; i++) {
if (i == 5) {
break; // Sale del ciclo cuando i llega a 5
}
cout << i << " ";
}
// Salida: 1 2 3 4
Analogía: Estás buscando tu libro en una estantería. Revisas libro por libro, y cuando lo encuentras, paras de buscar.
continue: saltar a la siguiente iteración
for (int i = 1; i <= 10; i++) {
if (i % 3 == 0) {
continue; // Salta los múltiplos de 3
}
cout << i << " ";
}
// Salida: 1 2 4 5 7 8 10
Analogía: Estás sirviendo comida a una fila de personas. Si alguien ya comió, lo saltas y sigues con el siguiente.
Patrones comunes en competencias
Leer N números y sumarlos
int n;
cin >> n;
int suma = 0;
for (int i = 0; i < n; i++) {
int x;
cin >> x;
suma += x;
}
cout << suma << endl;
Encontrar el máximo y mínimo
int n;
cin >> n;
int maximo = -1e9; // Un valor muy pequeño
int minimo = 1e9; // Un valor muy grande
for (int i = 0; i < n; i++) {
int x;
cin >> x;
maximo = max(maximo, x);
minimo = min(minimo, x);
}
cout << "Max: " << maximo << ", Min: " << minimo << endl;
Contar elementos que cumplen una condición
int n;
cin >> n;
int pares = 0;
for (int i = 0; i < n; i++) {
int x;
cin >> x;
if (x % 2 == 0) {
pares++;
}
}
cout << "Hay " << pares << " números pares" << endl;
Generar todos los pares
int n;
cin >> n;
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
cout << "Par: (" << i << ", " << j << ")" << endl;
}
}
Nota que j empieza en i + 1 para evitar pares repetidos.
Complejidad de los ciclos
- Un ciclo simple (
for i = 0..n): operaciones. - Dos ciclos anidados (
for i..n,for j..n): operaciones. - Tres ciclos anidados: operaciones.
// O(n) - funciona para n hasta ~10^8
for (int i = 0; i < n; i++) { ... }
// O(n²) - funciona para n hasta ~10^4
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++) { ... }
// O(n³) - funciona para n hasta ~500
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
for (int k = 0; k < n; k++) { ... }
En competencias, una regla general es que una computadora puede hacer aproximadamente operaciones por segundo. Si tu solución tiene y , eso son operaciones... ¡demasiadas! Necesitarás un algoritmo más eficiente.
Ejercicio de práctica
Imprime todos los números primos del 2 al N. Un número primo es aquel que solo es divisible entre 1 y sí mismo.
Entrada: 20
Salida: 2 3 5 7 11 13 17 19
Ver solución
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
for (int i = 2; i <= n; i++) {
bool esPrimo = true;
for (int j = 2; j * j <= i; j++) {
if (i % j == 0) {
esPrimo = false;
break;
}
}
if (esPrimo) {
cout << i << " ";
}
}
cout << endl;
return 0;
}
¿Por qué j * j <= i en lugar de j <= i? Porque si i tiene un divisor mayor que , necesariamente tiene otro menor que . Así revisamos muchos menos números. Por ejemplo, para verificar si 36 es primo, solo necesitamos revisar hasta 6 (porque ).
Siguiente paso
Aprende el Ciclo While para repetir cuando no sabes de antemano cuántas veces necesitas.
