Trougao brojeva
Učitava se n. Ispisati trougao u kome red i sadrži brojeve od 1 do i, razdvojene razmakom.
Primer
Ulaz
4Izlaz
1
1 2
1 2 3
1 2 3 4Ugnježdena petlja je petlja koja se nalazi u telu druge petlje. Za svaki prolaz spoljašnje petlje unutrašnja se izvrši cela. Tako se prave tablice, šare od zvezdica, prolazi kroz sve parove brojeva i kroz matrice.
Ako spoljašnja petlja ima n prolaza, a unutrašnja m, telo unutrašnje petlje izvrši se n · m puta. Promenljiva spoljašnje petlje (i) menja se sporo – kao kazaljka za sate, a unutrašnja (j) brzo – kao kazaljka za minute.
#include <stdio.h>
int main(void) {
/* spoljašnja petlja: i = 1, 2, 3 */
for (int i = 1; i <= 3; i++) {
/* unutrašnja petlja: za svako i, j ide od 1 do 2 */
for (int j = 1; j <= 2; j++) {
printf("i=%d j=%d\n", i, j);
}
}
return 0;
}
Ispis ima 3 · 2 = 6 redova. Uoči da se j svaki put ponovo kreće od 1, jer se unutrašnja petlja svaki put pokreće iz početka.
Spoljašnja petlja broji redove, unutrašnja kolone. Broj u redu i i koloni j je (i − 1) · 10 + j. Posle svakog reda ispisuje se prelazak u novi red \n.
#include <stdio.h>
int main(void) {
for (int i = 1; i <= 10; i++) { /* red */
for (int j = 1; j <= 10; j++) { /* kolona */
int broj = (i - 1) * 10 + j;
printf("%4d", broj); /* svaki broj zauzima 4 mesta */
}
printf("\n"); /* kraj reda */
}
return 0;
}
Format %4d poravnava brojeve u kolone. Isti zadatak može i jednom petljom (novi red posle svakog desetog broja) – vidi Petlje u C/C++ – primeri.
Tablica množenja dobija se istim kosturom – u preseku reda i i kolone j je i * j:
#include <stdio.h>
int main(void) {
int n;
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++)
printf("%4d", i * j);
printf("\n");
}
return 0;
}
Kod šara je ključno pitanje: koliko znakova ima red i? Unutrašnja petlja zavisi od i.
| Šara | Red i (od 1 do n) sadrži |
|---|---|
| pravougaonik n × m | m zvezdica |
| trougao | i zvezdica |
| obrnuti trougao | n − i + 1 zvezdica |
| piramida | n − i razmaka, pa 2·i − 1 zvezdica |
#include <stdio.h>
int main(void) {
int n;
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
/* razmaci ispred zvezdica */
for (int j = 1; j <= n - i; j++)
printf(" ");
/* zvezdice: 1, 3, 5, ... */
for (int j = 1; j <= 2 * i - 1; j++)
printf("*");
printf("\n");
}
return 0;
}
U jednom redu mogu biti i dve unutrašnje petlje jedna za drugom – prva za razmake, druga za zvezdice.
Mnogi zadaci traže proveru svakog para elemenata. Da se par ne broji dva puta (1+4 i 4+1), unutrašnja petlja kreće od i + 1:
#include <stdio.h>
int main(void) {
int n, k, a[100];
scanf("%d %d", &n, &k);
for (int i = 0; i < n; i++)
scanf("%d", &a[i]);
int broj = 0;
for (int i = 0; i < n; i++)
for (int j = i + 1; j < n; j++) /* samo parovi i < j */
if (a[i] + a[j] == k) {
printf("%d + %d\n", a[i], a[j]);
broj++;
}
printf("Ukupno parova: %d\n", broj);
return 0;
}
Ovakvih parova ima n·(n−1)/2. Za n = 1000 to je oko pola miliona provera – brzo. Za n = 100 000 već je 5 milijardi, pa na takmičenjima treba bolji algoritam (npr. tehnika dva pokazivača).
Naredba break prekida samo petlju u kojoj se nalazi – unutrašnju. Spoljašnja nastavlja sa sledećim brojem.
#include <stdio.h>
int main(void) {
int n;
scanf("%d", &n);
for (int x = 2; x <= n; x++) { /* svaki kandidat */
int prost = 1;
for (int d = 2; d * d <= x; d++) { /* delioci do korena iz x */
if (x % d == 0) {
prost = 0;
break; /* izlazi samo iz petlje po d */
}
}
if (prost)
printf("%d ", x);
}
printf("\n");
return 0;
}
Uslov d * d <= x je dovoljan: ako x ima delilac veći od korena, ima i manji. Više o tome: Prosti brojevi i faktorizacija.
| Petlje | Broj izvršavanja tela | Primer |
|---|---|---|
i od 1 do n, j od 1 do n | n² | tablica množenja |
j od i+1 do n | n·(n−1)/2 | svi parovi |
j od 1 do i | n·(n+1)/2 | trougao |
| tri ugnježdene petlje do n | n³ | sve trojke |
Gruba procena za takmičenja: računar uradi oko 108 prostih operacija u sekundi. Ako je n = 10 000, dve ugnježdene petlje (108) su na granici, a tri su prespore.
Za svaki zadatak postoji primer, uputstvo i rešenje. Rešenja su provereno tačna na primerima iz teksta.
Učitava se n. Ispisati trougao u kome red i sadrži brojeve od 1 do i, razdvojene razmakom.
41
1 2
1 2 3
1 2 3 4Učitavaju se n i m. Ispisati tablu sa n redova i m kolona u kojoj se smenjuju znakovi # i .; gornje levo polje je #.
3 5#.#.#
.#.#.
#.#.#Učitava se n. Ispisati sve trojke a < b < c ≤ n za koje važi a² + b² = c², svaku u novom redu, poređane po a, pa po b.
203 4 5
5 12 13
6 8 10
8 15 17
9 12 15
12 16 20j), ne ista kao spoljašnje (i) – inače se spoljašnja petlja pokvari.for (int j = 1; ...)), ne pre nje.printf("\n") za kraj reda ide posle unutrašnje petlje, a pre zatvorene zagrade spoljašnje.break izlazi samo iz unutrašnje petlje; za izlaz iz obe koristi promenljivu-zastavicu i proveri je u uslovu spoljašnje petlje.1. Koliko puta se izvrši telo: for (i=0;i<5;i++) for (j=0;j<4;j++) ...?
2. Koliko zvezdica ima red i u piramidi?
3. Iz koje petlje izlazi break napisan u unutrašnjoj petlji?
4. Zašto unutrašnja petlja kod parova počinje od i + 1?