Cod sursa(job #1073314)

Utilizator dr_personalityEftime Andrei Horatiu dr_personality Data 5 ianuarie 2014 22:08:03
Problema Generare de permutari Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.02 kb
#include <stdio.h>

int st[20], n,k,count=1,act=1,v[30];

void back(int k)
{
	if (k == n)
	{
		// Daca k == n+1, inseamna ca am generat deja
		// n elemente, adica avem o solutie:
		// st[0], st[1], st[2], st[3]
		// O afisam si acesta este pasul de oprire din recursivitate
		for (int i = 0; i < n; i++)
		{
			printf("%d ", st[i]);
		}
		printf("\n");
	}
	else
	{
		// Altfel, avem deja generate elemente pentru pozitiile
		// st[0], st[1], st[2], st[k-1]
		
		// Trebuie sa generam st[k] astfel incat 
		// acesta sa fie diferit de cele generate anterior
		// st[0], st[1], st[2]
		
		// Facem asta prin a incerca, pe rand fiecare numar 
		// de la 1 la n
	
		for (int i = 1; i <= n; i++)
		{
			int unic = 1;
			
			// Pentru fiecare numar incercat, il comparam cu cele generate anterior
			for (int j = 0; j <= k -1; j++)
			{
				if (st[j] == i)
				{
					// Daca a fost deja generat, oprim verificare
					// (O mica optimizarE)
					unic = 0;
					break;
				}
			}
			
			if (unic == 1)
			{
				// Am ajuns aici, deci inseamna ca numarul i este unic
				// Il punem pe pozitia k si apelam back(k+1)
				st[k] = i;
				back(k+1);
				// Important de precizat e ca fiecare apel salveaza pe stiva variabilel locale din acel punct
				// In cazul nostru, variaila i
				// asa ca atunci cand va reveni aici, va continua cu for-ul din punctul in care s-a apelat;
			
				// Se poate verifica asta cu debuggerul din visual studio, pus breakpoint  in back(k+1), dat continue de 3 ori
				// si vazut stiva (fereastra Call Stack, langa Breakpoints); si acolo se vad toate apelurile
				// Daca adaugam un watch la variabila i si pe callstack schimbam de la un apel la altul observam diferite valori ale variabilei i
			}
		}
	}
}

int main()
{
	freopen("permutari.in","r",stdin);
	freopen("permutari.out","w",stdout);
	scanf("%d",&n);
	// Primul apel este back(1), echivalent cu:
	//		- nu am generat nimic pana acum, si incepem prin a cauta elemente pentru prima pozitie
	back(0);

	return 0;
}