/*
Spiralna kvadratna matrica reda n x n
pocevsi od gornjeg levog (GL) elementa M[0][0]
popunjava se u pravcu kazaljke na satu
brojevima od 1 do n x n.
*/
#include <stdio.h>
#include <stdlib.h>
#define MAX_SIZE 20
// Prikazuje matricu M[][] koja ima r redova i k kolona
void prikazi_matricu( char *tekst, int M[][MAX_SIZE], int r, int k )
{
int i, j;
printf("\n%s\n\n",tekst);
for(i=0;i<r;i++) { // Stampamo matricu M[][]
for(j=0;j<k;j++)
printf("%4d",M[i][j]);
printf("\n\n"); // novi red matrice
}
printf("\n\n");
}
// Setuje sve elemente matrice M[][] koja ima r redova i k kolona na vrednost int broj
void setuj_matricu_na_broj( int M[][MAX_SIZE], int r, int k, int broj ) {
int i, j;
for(i=0;i<r;i++)
for(j=0;j<k;j++)
M[i][j] = broj;
}
// Ovaj problem se pojednostavljuje popunjavanjem matrice prsten-po-prsten.
// Krecemo od spoljnih ivica i popunjavamo zasebno sva cetiri smera
// redosledom: desno, dole, levo, gore.
// Zatim popunjavamo sledeci prsten ...
void main (void)
{
int M[MAX_SIZE][MAX_SIZE], n;
int broj, r, k, r_min, k_min, r_max, k_max;
printf("\n Unesi broj (2 <= n <= 20) redova (tj. kolona) kvadratne matrice M[][], n = ");
scanf("%d", &n);
printf("\n\n");
if ( n < 2 || n > 20 ) {
printf("\n Zbog prikaza nema smisla da red matrice bude manji od 2 ili veci od 20 !!!\n");
exit(1);
}
printf("\n Red matrice je n = %d \n\n",n);
// Setujemo sve elemente matrice M na nulu da bi smo se kretali po matrici
// proveravajuci uslov: while( M[r][k] == 0 )
setuj_matricu_na_broj(M,n,n,0);
// prikazi_matricu(" Matrica sa nulama je: ", M, n, n);
// pocetne vrednosti
broj=1; // broj koji se upisuje u matricu M
r=0; // tekuci red
k=0; // tekuca kolona
r_min = 0; // minimalni red // granice tekuceg prstena
k_min = 0; // minimalna kolona
r_max = n-1; // maksimalni red
k_max = n-1; // maksimalna kolona
while ( broj < n*n ){ // broj ide od 1 do n*n
// u desno
while( M[r][k] == 0 && k <= k_max )
M[r][k++] = broj++;
// na dole
r++; // povecavamo tekuci red jer idemo na dole
k--; // smanjujemo tekucu kolonu jer smo je poslednji put nepotrebno uvecali
while( M[r][k] == 0 && r <= r_max )
M[r++][k] = broj++;
// u levo
r--; // smanjujemo tekuci red jer smo ga poslednji put nepotrebno uvecali
k--; // smanjujemo tekucu kolonu jer idemo u levo
while( M[r][k] == 0 && k >= k_min )
M[r][k--] = broj++;
// na gore
r--; // smanjujemo tekuci red jer idemo na gore
k++; // povecavamo tekucu kolonu jer smo je poslednji put nepotrebno smanjili
while( M[r][k] == 0 && r >= r_min )
M[r--][k] = broj++;
r_min++; // popunili smo spoljni okvir matrice M i sada ga suzavamo
k_min++;
r_max--;
k_max--;
r = r_min; // nove pocetne vrednosti za sledeci unutrasnji prsten matrice M
k = k_min;
}
// Ako je n neparno, gornji algoritam ostavlja nepopunjen broj
// u centru matrice M[n/2][n/2] i zato ga sada popunimo:
if ( n % 2 ) // ako je n neparno
M[n/2][n/2] = n*n;
prikazi_matricu(" Spiralna matrica je: ", M, n, n);
}