Задаци: Цртежи помоћу карактера¶
Алгоритми и програми у програмском језику C: Цртежи помоћу карактера.
Квадрат од звездица¶
Прочитај текст задатка.
Можемо приметити да се квадрат састоји од \(n\) редова, а да се у сваком реду налази \(n\) звездица. Зато програм можемо организовати помоћу угнежђених петљи. Спољна петља се извршава \(n\) пута и у њеном телу се исписује један ред. То се врши тако што се у телу унутрашње петље која се извршава \(n\) пута исписује једна звездица, а након те унутрашње петље се исписује прелазак у нови ред.
Предложено решење задатка
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main(void)
{
int n;
scanf("%d", &n);
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
printf("*");
printf("\n");
}
return 0;
}
Троугао од звездица¶
Прочитај текст задатка.
За дати број \(n\) троугао садржи \(n\) редова. Сваки ред ћемо исписивати у петљи у којој променљива \(i\) мења вредност од 0 до \(n-1\). Размотримо случај \(n=4\). У првом реду (када је \(i=0\)) потребно је исписати три размака и једну звездицу, у другом (када је \(i=1\)) потребно је исписати два размака и три звездице, у трећем (када је \(i=2\)) потребно је један размак и пет звездица и у четвртом (када је \(i=3\)) потребно је исписати нула размака и седам звездица. Може се закључити да је број размака једнак \(n-i-1\), а број звездица једнак \(2i+1\) (иако је извођење ових релација прилично очигледно, можемо приметити да број размака чини аритметички низ који креће од \(n-1\) и чија је разлика суседних елемената \(-1\), док број звездица чини аритметички низ који креће од 1 и чија је разлика суседних елемената \(2\)). Исписивање датог броја појављивања неког карактера можемо реализовати једноставно у петљи. Тако задатак можемо решити помоћу две унутрашње петље (једне у којој се исписују размаци и једне у којој се исписују звездице).
Предложено решење задатка (1)
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main(void)
{
int n;
scanf("%d", &n);
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n - i - 1; j++)
printf(" ");
for (int j = 0; j < 2 * i + 1; j++)
printf("*");
printf("\n");
}
return 0;
}
Број звездица и размака није неопходно експлицитно израчунавати, већ је могуће одржавати две посебне променљиве у којима се памте ови бројеви.
Предложено решење задатка (2)
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main(void)
{
int n;
scanf("%d", &n);
int br = n - 1, bz = 1;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < br; j++)
printf(" ");
br -= 1;
for (int j = 0; j < bz; j++)
printf("*");
bz += 2;
printf("\n");
}
return 0;
}
Ромб од звездица¶
Прочитај текст задатка.
Ромб се састоји од \(n\) редова, а у сваком реду се прво исписује одређени број размака, а затим и \(n\) звездица. Претпоставимо да ћемо то остварити спољашњом петљом у којој \(i\) узима вредности од \(0\) до \(n-1\). Обележимо за сваки ред вредност бројача \(i\), број звездица и број размака.
i br bz
***** 0 4 5
***** 1 3 5
***** 2 2 5
***** 3 1 5
***** 4 0 5
Можемо приметити да је у сваком реду збир броја размака и бројача \(i\) константан и једнак вредности \(n-1\), па је стога број размака увек једнак \(n-1-i\). Дакле у телу спољашње петље имаћемо унутрашњу петљу која исписује \(n-1-i\) размака, а затим и другу унутрашњу петљу која исписује \(n\) звездица. На крају тела спољашње петље (након обе унутрашње) прелазимо у нови ред.
Предложено решење задатка (1)
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main(void)
{
int n;
scanf("%d", &n);
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n - 1 - i; j++)
printf(" ");
for (int j = 0; j < n; j++)
printf("*");
printf("\n");
}
return 0;
}
Спољашњу петљу можемо реализовати тако да бројач \(i\) креће од \(n-1\) и спушта се до \(0\) и тада би број размака био једнак \(i\).
Предложено решење задатка (2)
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main(void)
{
int n;
scanf("%d", &n);
for (int i = n - 1; i >= 0; i--)
{
for (int j = 0; j < i; j++)
printf(" ");
for (int j = 0; j < n; j++)
printf("*");
printf("\n");
}
return 0;
}
Једно могуће решење је и да број размака пратимо помоћу посебне променљиве коју иницијализујемо на \(n-1\) и умањујемо је за 1 на крају тела унутрашње петље.
Предложено решење задатка (3)
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main(void)
{
int n;
scanf("%d", &n);
for (int i = 0, r = n - 1; i < n; i++, r--)
{
for (int j = 0; j < r; j++)
printf(" ");
for (int j = 0; j < n; j++)
printf("*");
printf("\n");
}
return 0;
}
Ћилим од звездица¶
Прочитај текст задатка.
Приметимо да се ћилим може хоризонталном линијом поделити на два дела. Нумеришимо редове бројевима од \(0\) до \(2n-2\). Пошто је цртеж симетричан, пожељно је да креирамо нумерацију која то осликава тј. да првих \(n\) редова нумеришемо бројевима од \(0\) до \(n-1\), а затим да наредних \(n-1\) редова нумеришемо бројевима који опадају од \(n-2\) до \(0\). Један начин да се то уреди је да се набрајање редова врши у две независне петље (прва која броји унапред од \(0\) до \(n-1\) и друга која броји уназад од \(n-2\) до \(0\)), но пошто би те петље имале идентична тела, ефикасније решење добијамо ако конструишемо функцију која нумерацију од \(0\) до \(2n-2\) пресликава у нашу жељену нумерацију. Једна таква функција је \(j=n-1-|n-1-i|\) (за \(i\leq n-1\) њена вредност једнака је \(n-1-(n-1-i)=i\), док је за \(i\geq n\) њена вредност једнака \(n-1-(1+i-n)=2n-2-i\)).
n = 4
i j r z
0 0 ******** 0 4
1 1 *** *** 2 3
2 2 ** ** 4 2
3 3 * * 6 1
4 2 ** ** 4 2
5 1 *** *** 2 3
6 0 ******** 0 4
У сваком реду ћемо прво исписивати \(z\) звездица, затим \(r\) размака, затим поново \(z\) звездица и након тога прећи у нови ред. Уочимо како број звездица \(z\) и број размака \(r\) зависе од вредности \(j\) и \(n\).
Пошто бројање \(j\) креће од нуле, важи да је \(r=2\cdot j\). Приметимо да у претходном примеру у сваком реду важи \(j+z=4=n\) и зато је \(z=n-j\).
У телу петље исписујемо један ред (петља у себи садржи неколико угнежђених петљи или позиве функција у којима се те угнежђене петље реализују). Прво се исписује \(z=n-j\) звездица, затим \(r=2\cdot j\) размака, затим поново \(z=n-j\) звездица и на крају се прелази у нови ред.
Предложено решење задатка (1)
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int n;
scanf("%d", &n);
for (int i = 0; i < 2 * n - 1; i++)
{
int j = n - 1 - abs(n - 1 - i);
for (int z = 0; z < n - j; z++)
printf("*");
for (int r = 0; r < 2 * j; r++)
printf(" ");
for (int z = 0; z < n - j; z++)
printf("*");
printf("\n");
}
return 0;
}