<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://www.algopedia.ro/wiki/index.php?action=history&amp;feed=atom&amp;title=Clasa7</id>
	<title>Clasa7 - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://www.algopedia.ro/wiki/index.php?action=history&amp;feed=atom&amp;title=Clasa7"/>
	<link rel="alternate" type="text/html" href="https://www.algopedia.ro/wiki/index.php?title=Clasa7&amp;action=history"/>
	<updated>2026-08-03T09:40:43Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.44.2</generator>
	<entry>
		<id>https://www.algopedia.ro/wiki/index.php?title=Clasa7&amp;diff=12923&amp;oldid=prev</id>
		<title>Dan: /* BFS Continuare */</title>
		<link rel="alternate" type="text/html" href="https://www.algopedia.ro/wiki/index.php?title=Clasa7&amp;diff=12923&amp;oldid=prev"/>
		<updated>2015-10-22T13:22:31Z</updated>

		<summary type="html">&lt;p&gt;&lt;span class=&quot;autocomment&quot;&gt;BFS Continuare&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;= Recapitulare materie =&lt;br /&gt;
&lt;br /&gt;
== Secvență bitonă prin rotație ==&lt;br /&gt;
Verificare secvență bitonă prin rotație. O secvență este bitonă dacă mai întîi crește și apoi, eventual, descrește. O secvență bitonă prin rotație este o secvență care fie este bitonă, fie poate fi făcută bitonă prin rotații succesive. Problema trebuie rezolvată fără a folosi vectori, similar cu problema secvenței crescătoare prin rotație. Soluție liniară. Dacă ați înțeles algoritmul încercați-vă forțele rezolvînd problema [http://varena.ro/problema/bitona secvență bitonă].&lt;br /&gt;
&lt;br /&gt;
== Problema selecției ==&lt;br /&gt;
Dat un șir de &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; numere și o poziție &amp;lt;tt&amp;gt;k&amp;lt;/tt&amp;gt; în acel șir să se spună ce element s-ar afla pe acea poziție dacă șirul ar fi sortat. Aplicăm repetat pivotarea quicksort. Calcul aproximativ al complexității pe cazul mediu: este O(n), în loc de O(n log n) dacă am fi făcut sortare. Dacă ați înțeles algoritmul încercați-vă forțele rezolvînd problema [http://varena.ro/problema/selectie selecție].&lt;br /&gt;
&lt;br /&gt;
== Elementul majoritar ==&lt;br /&gt;
Dat un vector cu &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; elemente să se spună dacă conține un element majoritar. Un element majoritar este un element care apare de cel puțin &amp;lt;tt&amp;gt;n/2 + 1&amp;lt;/tt&amp;gt; ori. Încercați să dați o soluție mai bună decît sortarea. Am discutat variante de algoritmi:&lt;br /&gt;
* Forță brută: luăm fiecare element din vector și vedem de cîte ori apare. Complexitate O(n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;).&lt;br /&gt;
* Prin sortare: sortăm vectorul și căutăm subsecvența de elemente egale de lungime maximă. Complexitate: O(n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;) cu sortare prin selecție, O(n log n) cu quicksort.&lt;br /&gt;
* Algoritmul optim: considerăm primul element drept candidat, iar apoi parcurgem vectorul, numărînd de cîte ori apare candidatul. De fiecare dată cînd apare un element diferit de candidat decrementăm contorul. Dacă contorul ajunge negativ repornim procedura cu elementul curent drept nou candidat. În final dacă candidatul are măcar o apariție îl verificăm de cîte ori apare în vector. Complexitate O(n).&lt;br /&gt;
&lt;br /&gt;
Dacă ați înțeles algoritmul încercați-vă forțele rezolvînd problema [http://varena.ro/problema/majoritar elementul majoritar].&lt;br /&gt;
&lt;br /&gt;
== Paranteze ==&lt;br /&gt;
Verificare expresie cu paranteze. Se dă o expresie cu paranteze rotunde, pătrate și acolade: &amp;lt;nowiki&amp;gt;(), [] și {}&amp;lt;/nowiki&amp;gt;. Ele pot să apară în orice ordine, adică și &amp;lt;nowiki&amp;gt;)&amp;lt;/nowiki&amp;gt; după &amp;lt;nowiki&amp;gt;]&amp;lt;/nowiki&amp;gt;. Să se spună dacă o expresie este corectă. Exemple: &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;([()[]()]())[]&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; este corectă, &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;([)], )(, ([()]&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; nu sînt corecte. Am discutat despre cazul mai simplu, în care avem doar paranteze rotunde, apoi am generalizat la cazul cu mai multe tipuri de paranteze, folosind o stivă.&lt;br /&gt;
&lt;br /&gt;
== Baze de numerație ==&lt;br /&gt;
Un &amp;#039;&amp;#039;sistem de numerație&amp;#039;&amp;#039; este un mod de a exprima numerele. Cu alte cuvinte o notație matematică pentru a reprezenta numerele folosind cifre sau alte simboluri într-o manieră consecventă. Sistemul de numerație este cel care face ca simbolurile &amp;quot;11&amp;quot; să fie interpretate ca simbolul binar al lui trei, simbolul zecimal al lui unsprezece, sau simbolul altor numere în diferite baze.&lt;br /&gt;
&lt;br /&gt;
Un sistem de numerație:&lt;br /&gt;
&lt;br /&gt;
* Reprezintă o mulțime utilă de numere (de ex. toți întregii, sau numerele raționale)&lt;br /&gt;
* Reprezintă unic fiecare număr&lt;br /&gt;
* Ideal, ar trebui să reflecte structura algebrică și aritmetică a numerelor&lt;br /&gt;
&lt;br /&gt;
=== Conversia de la baza 10 la baza 2 ===&lt;br /&gt;
Pentru a converti un număr &amp;#039;&amp;#039;n&amp;#039;&amp;#039; din baza 10 în baza 2 îl vom împărți la 2 în mod repetat, pîna ce obținem cîtul zero. Apoi vom colecta resturile obținute de la ultimul către primul. Aceste resturi sînt cifrele numărului în baza doi, de la stînga la dreapta.&lt;br /&gt;
&lt;br /&gt;
==== Exemplul 1 ====&lt;br /&gt;
Să convertim numărul &amp;#039;&amp;#039;26&amp;#039;&amp;#039; la baza 2:&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;26 = 2×13 + 0&amp;#039;&amp;#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;13 = 2×6 + 1&amp;#039;&amp;#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;6 = 2×3 + 0&amp;#039;&amp;#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;3 = 2×1 + 1&amp;#039;&amp;#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;1 = 2×0 + 1&amp;#039;&amp;#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;26&amp;lt;sub&amp;gt;(10)&amp;lt;/sub&amp;gt; = 11010&amp;lt;sub&amp;gt;(2)&amp;lt;/sub&amp;gt;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
==== Exemplul 2 ====&lt;br /&gt;
Să convertim numărul &amp;#039;&amp;#039;37&amp;#039;&amp;#039; la baza 2:&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;37 = 2×18 + 1&amp;#039;&amp;#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;18 = 2×9 + 0&amp;#039;&amp;#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;9 = 2×4 + 1&amp;#039;&amp;#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;4 = 2×2 + 0&amp;#039;&amp;#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;2 = 2×1 + 0&amp;#039;&amp;#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;1 = 2×0 + 1&amp;#039;&amp;#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;37&amp;lt;sub&amp;gt;(10)&amp;lt;/sub&amp;gt; = 100101&amp;lt;sub&amp;gt;(2)&amp;lt;/sub&amp;gt;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== Conversia de la baza 2 la baza 10 ===&lt;br /&gt;
Această conversie se poate face direct, scriind fiecare cifră binară explicit înmulțită cu puterea corespunzătoare a lui 2.&lt;br /&gt;
&lt;br /&gt;
==== Exemplul 3 ====&lt;br /&gt;
Să convertim numărul &amp;#039;&amp;#039;100101&amp;#039;&amp;#039; din baza 2 în baza 10:&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;100101&amp;lt;sub&amp;gt;(2)&amp;lt;/sub&amp;gt; = 1×2&amp;lt;sup&amp;gt;5&amp;lt;/sup&amp;gt; + 0×2&amp;lt;sup&amp;gt;4&amp;lt;/sup&amp;gt; + 0×2&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt; + 1×2&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; + 0×2&amp;lt;sup&amp;gt;1&amp;lt;/sup&amp;gt; + 1×2&amp;lt;sup&amp;gt;0&amp;lt;/sup&amp;gt;&amp;#039;&amp;#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;100101&amp;lt;sub&amp;gt;(2)&amp;lt;/sub&amp;gt; = 1×32 + 0×16 + 0×8 + 1×4 + 0×2 + 1×1&amp;#039;&amp;#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;100101&amp;lt;sub&amp;gt;(2)&amp;lt;/sub&amp;gt; = 32 + 4 + 1&amp;#039;&amp;#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;100101&amp;lt;sub&amp;gt;(2)&amp;lt;/sub&amp;gt; = 37&amp;lt;sub&amp;gt;(10)&amp;lt;/sub&amp;gt;&amp;#039;&amp;#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Deși această metodă a evaluării directe prin dezvoltarea numărului cu puterile lui doi este mai simplu de înțeles, există un algoritm ceva mai rapid. Începînd cu rezultatul &amp;#039;&amp;#039;0&amp;#039;&amp;#039;, parcurgem cifrele binare de la stînga la dreapta. Pentru fiecare cifră a numărului de la intrare vom înmulți rezultatul cu doi și vom aduna cifra la rezultat.&lt;br /&gt;
&lt;br /&gt;
==== Exemplul 4 ====&lt;br /&gt;
Să convertim numărul &amp;#039;&amp;#039;11010&amp;#039;&amp;#039; din baza 2 în baza 10 folosind acest algoritm:&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;0×2 + 1 = 1&amp;#039;&amp;#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;1×2 + 1 = 3&amp;#039;&amp;#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;3×2 + 0 = 6&amp;#039;&amp;#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;6×2 + 1 = 13&amp;#039;&amp;#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;13×2 + 0 = 26&amp;#039;&amp;#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;11010&amp;lt;sub&amp;gt;(2)&amp;lt;/sub&amp;gt; = 26&amp;lt;sub&amp;gt;(10)&amp;lt;/sub&amp;gt;&amp;#039;&amp;#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Acesta este algoritmul pe care îl vom prefera pentru conversia numerelor din baza 2 în baza 10.&lt;br /&gt;
&lt;br /&gt;
=== Conversie de la baza 10 la baza 2 ===&lt;br /&gt;
Se citește &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; de maxim 18 cifre. Să se afișeze reprezentarea lui în baza 2.&lt;br /&gt;
&lt;br /&gt;
Varianta clasică, despre care am vorbit mai sus, este cea în care reținem resturile împărțirii repetate la doi și apoi le afișăm în ordine inversă:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int cifre[60]; // 60 de cifre binare = 18 cifre zecimale&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
  FILE *fin, *fout;&lt;br /&gt;
  int m, i;&lt;br /&gt;
  long long n; // 18 cifre inseamna long long&lt;br /&gt;
&lt;br /&gt;
  fin = fopen( &amp;quot;b10b2.in&amp;quot;, &amp;quot;r&amp;quot; );&lt;br /&gt;
  fscanf( fin , &amp;quot;%lld&amp;quot;, &amp;amp;n );&lt;br /&gt;
  fclose( fin );&lt;br /&gt;
&lt;br /&gt;
  m = 0;&lt;br /&gt;
  while ( n &amp;gt; 0 ) {&lt;br /&gt;
    cifre[m] = n % 2; // extragem pe rind resturile impartirii la 2&lt;br /&gt;
    m++;&lt;br /&gt;
    n /= 2;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  fout = fopen( &amp;quot;b10b2.out&amp;quot;, &amp;quot;w&amp;quot; );&lt;br /&gt;
  for ( i = m - 1; i &amp;gt;= 0; i-- ) // afisam resturile in ordine inversa&lt;br /&gt;
    fprintf( fout, &amp;quot;%d&amp;quot;, cifre[i] );&lt;br /&gt;
  fprintf( fout, &amp;quot;\n&amp;quot; );&lt;br /&gt;
  fclose( fout );&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Conversie de la baza 2 la baza 10 ===&lt;br /&gt;
La intrare avem o înșiruire de caractere 0 și 1, neseparate de spații și terminate cu final de linie. Ele reprezintă un număr în baza 2 de cel mult 60 de cifre binare. Să se convertească acest număr la baza 10 și să se afișeze.&lt;br /&gt;
&lt;br /&gt;
Vom proceda precum am discutat mai sus. Vom citi cifrele binare una cîte una și le vom adăuga la coada lui &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt;, înmulțindu-l pe acesta cu doi și apoi adunînd cifra. Iată programul:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
  FILE *fin, *fout;&lt;br /&gt;
  long long n; // 18 cifre inseamna long long&lt;br /&gt;
  char ch;&lt;br /&gt;
&lt;br /&gt;
  fin = fopen( &amp;quot;b2b10.in&amp;quot;, &amp;quot;r&amp;quot; );&lt;br /&gt;
  n = 0;&lt;br /&gt;
  ch = fgetc( fin );&lt;br /&gt;
  while( ch != &amp;#039;\n&amp;#039; ) {&lt;br /&gt;
    n = n * 2 + ch - &amp;#039;0&amp;#039;;&lt;br /&gt;
    ch = fgetc( fin );&lt;br /&gt;
  }&lt;br /&gt;
  fclose( fin );&lt;br /&gt;
&lt;br /&gt;
  fout = fopen( &amp;quot;b2b10.out&amp;quot;, &amp;quot;w&amp;quot; );&lt;br /&gt;
  fprintf( fout, &amp;quot;%lld\n&amp;quot;, n );&lt;br /&gt;
  fclose( fout );&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Aplicație: submulțimile unei mulțimi ===&lt;br /&gt;
&amp;#039;&amp;#039;Aceasta este o problemă clasică în matematică și informatică.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Rezolvați în clasă următorul exercițiu: să se afișeze toate submulțimile nevide ale mulțimii &amp;lt;nowiki&amp;gt;{ 1, 2, 3, ..., n }&amp;lt;/nowiki&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Cum abordăm această problemă? La prima vedere pare foarte grea. Va trebui, probabil, să afișăm toate submulțimile de un element. Aceasta e simplu. Apoi cele de două elemente. Tot simplu, vom selecta perechile cu două bucle &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;. Apoi cele cu trei elemente. Hmmm, de data asta avem nevoie de trei bucle &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;. Apoi de patru. Apoi de cinci. Cînd se oprește? Răspunsul depinde de &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt;. Dar stai! Nu putem scrie un număr variabil de bucle &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt; una într-alta!&lt;br /&gt;
&lt;br /&gt;
Ne trebuie o altă abordare. Vom codifica mulțimile. Cum? Foarte simplu: folosind vectorul lor caracteristic. Pentru fiecare element al mulțimii, de la 1 la &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt;, vom avea un element în vectorul &amp;lt;tt&amp;gt;v&amp;lt;/tt&amp;gt;. Pentru o submulțime dată &amp;lt;tt&amp;gt;v[i]&amp;lt;/tt&amp;gt; este 1 dacă elementul &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; apare în submulțime.&lt;br /&gt;
&lt;br /&gt;
Acest mod de codificare demonstrează un lucru interesant: numărul de submulțimi al unei mulțimi, incluzînd mulțimea vidă, este 2&amp;lt;sup&amp;gt;n&amp;lt;/sup&amp;gt;. Interesant!&lt;br /&gt;
&lt;br /&gt;
Cum vom folosi acest vector? Destul de neclar. Ne-ar trebui un mod în care să variem toate elementele sale de la zero la unu. Și iar ne întoarcem la buclele &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt; una într-alta. Dar există un mod natural în care elementele pot trece prin toate combinațiile posibile de 0 și 1: dacă în loc să folosim un vector cu &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; elemente folosim un număr binar cu &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; cifre. Dacă pornim cu numărul binar de la zero și îl incrementăm pînă ce ajungem la 2&amp;lt;sup&amp;gt;n&amp;lt;/sup&amp;gt; cele &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; cifre ale sale vor trece prin toate configurațiile posibile. Exact ce ne dorim!&lt;br /&gt;
&lt;br /&gt;
În concluzie, care este algoritmul? Iată-l descris mai jos:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;1. Pentru i de la 1 la 2^n - 1&lt;br /&gt;
    1.1 Descompune i în baza 2&lt;br /&gt;
    1.2 Pentru fiecare cifră binară 1 care se află pe poziția j&lt;br /&gt;
        1.2.1 Afișează j&lt;br /&gt;
    1.3 Sfîrșit de submulțime, treci la linia următoare&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Remarcați că algoritmul nu folosește vectori! Vă invit să rezolvați problema [http://varena.ro/problema/submultimi1 submulțimi1] la vianuarena, folosind acest algoritm. După ce o rezolvați, pentru verificare, iată codul complet mai jos:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; style=&amp;quot;border: dashed&amp;quot;&amp;gt;#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
  FILE *fin, *fout;&lt;br /&gt;
  int n, m, i, p2max, p;&lt;br /&gt;
&lt;br /&gt;
  fin = fopen( &amp;quot;submultimi1.in&amp;quot;, &amp;quot;r&amp;quot; );&lt;br /&gt;
  fscanf( fin, &amp;quot;%d&amp;quot;, &amp;amp;n );&lt;br /&gt;
  fclose( fin );&lt;br /&gt;
&lt;br /&gt;
  p2max = 1; // calculam 2^n, numarul pina unde trebuie sa numaram&lt;br /&gt;
  for ( i = 0; i &amp;lt; n; i++ )&lt;br /&gt;
    p2max *= 2;&lt;br /&gt;
&lt;br /&gt;
  fout = fopen( &amp;quot;submultimi1.out&amp;quot;, &amp;quot;w&amp;quot; );&lt;br /&gt;
  for ( i = 1; i &amp;lt; p2max; i++ ) {  // numaram de la 1 la 2^n exclusiv&lt;br /&gt;
    m = i;                         // copiem contorul, sa nu il pierdem&lt;br /&gt;
    for ( p = 1; p &amp;lt;= n; p++ ) {   // obtinem pe rind cifrele binare&lt;br /&gt;
      if ( m % 2 == 1 )            // 1 inseamna ca pozitia apartine multimii&lt;br /&gt;
        fprintf( fout, &amp;quot;%d &amp;quot;, p ); // afisam pozitia cifrei 1, p&lt;br /&gt;
      m /= 2;&lt;br /&gt;
    }&lt;br /&gt;
    fprintf( fout, &amp;quot;\n&amp;quot; );         // am afisat o submultime, linie noua&lt;br /&gt;
  }&lt;br /&gt;
  fclose( fout );&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Calculul multiplicității unui număr în &amp;#039;&amp;#039;n&amp;#039;&amp;#039;&amp;lt;nowiki&amp;gt;!&amp;lt;/nowiki&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
=== Calculul multiplicității unui număr prim în &amp;#039;&amp;#039;n&amp;#039;&amp;#039;&amp;lt;nowiki&amp;gt;!&amp;lt;/nowiki&amp;gt; ===&lt;br /&gt;
Matematicianul [http://en.wikipedia.org/wiki/Adrien-Marie_Legendre Adrien-Marie_Legendre] a descoperit că multiplicitatea (exponentul) unui număr prim &amp;#039;&amp;#039;p&amp;#039;&amp;#039; care apare în descompunerea în factori primi a lui &amp;#039;&amp;#039;n&amp;#039;&amp;#039;&amp;lt;nowiki&amp;gt;!&amp;lt;/nowiki&amp;gt; poate fi exprimată exact ca:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;Exp(p,n!) = \left \lfloor \frac{n}{p} \right \rfloor + \left \lfloor \frac{n}{p^2} \right \rfloor + \left \lfloor \frac{n}{p^3} \right \rfloor + \cdots = \sum_{i=1}^{\infty} \left \lfloor \frac{n}{p^i} \right \rfloor .&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Acest fapt se bazează pe numărarea factorilor &amp;#039;&amp;#039;p&amp;#039;&amp;#039; ai întregilor de la 1 la&amp;amp;nbsp;&amp;#039;&amp;#039;n&amp;#039;&amp;#039;. Numărul multiplilor lui &amp;#039;&amp;#039;p&amp;#039;&amp;#039; în numerele de la 1 la &amp;#039;&amp;#039;n&amp;#039;&amp;#039; este &amp;lt;math&amp;gt;\textstyle \left \lfloor \frac{n}{p} \right \rfloor&amp;lt;/math&amp;gt;; dar această formulă numără numerele cu doi factori &amp;#039;&amp;#039;p&amp;#039;&amp;#039; o singură dată. De aceea trebuie să mai numărăm încă &amp;lt;math&amp;gt;\textstyle \left \lfloor \frac{n}{p^2} \right \rfloor&amp;lt;/math&amp;gt; factori ai lui &amp;#039;&amp;#039;p&amp;#039;&amp;#039;. În mod similar pentru trei, patru, cinci factori, pînă la infinit. Însă suma este finită deoarece &amp;#039;&amp;#039;p&amp;#039;&amp;#039;&amp;lt;sup&amp;gt;&amp;amp;nbsp;&amp;#039;&amp;#039;i&amp;#039;&amp;#039;&amp;lt;/sup&amp;gt; este mai mic sau egal cu &amp;#039;&amp;#039;n&amp;#039;&amp;#039; într-un număr finit de valori ale lui &amp;#039;&amp;#039;i&amp;#039;&amp;#039;, drept care funcția parte întreagă va fi zero pentru toate celelalte valori.&lt;br /&gt;
&lt;br /&gt;
Cînd scriem programul pentru calculul exponentului ne vom opri la acel &amp;#039;&amp;#039;i&amp;#039;&amp;#039; pentru care &amp;#039;&amp;#039;p&amp;lt;sup&amp;gt;i&amp;lt;/sup&amp;gt; &amp;gt; n&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
=== Calculul multiplicității unui număr prim la o putere în &amp;#039;&amp;#039;n&amp;#039;&amp;#039;&amp;lt;nowiki&amp;gt;!&amp;lt;/nowiki&amp;gt; ===&lt;br /&gt;
Este simplu de demonstrat că dacă avem un număr prim &amp;#039;&amp;#039;p&amp;#039;&amp;#039; la o putere &amp;#039;&amp;#039;k&amp;#039;&amp;#039; atunci multiplicitatea lui &amp;#039;&amp;#039;p&amp;lt;sup&amp;gt;k&amp;lt;/sup&amp;gt;&amp;#039;&amp;#039; în &amp;#039;&amp;#039;n&amp;#039;&amp;#039;&amp;lt;nowiki&amp;gt;!&amp;lt;/nowiki&amp;gt; este&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;Exp(p^k,n!) = \frac{Exp(p,n!)}{k}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Calculul multiplicității unui număr oarecare în &amp;#039;&amp;#039;n&amp;#039;&amp;#039;&amp;lt;nowiki&amp;gt;!&amp;lt;/nowiki&amp;gt; ===&lt;br /&gt;
Este simplu să arătăm că dacă avem un număr &amp;#039;&amp;#039;a&amp;#039;&amp;#039; a cărui descompunere în factori primi este&lt;br /&gt;
&lt;br /&gt;
:&amp;#039;&amp;#039;a = p&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;&amp;lt;sup&amp;gt;k&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;&amp;lt;/sup&amp;gt; • p&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;&amp;lt;sup&amp;gt;k&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;&amp;lt;/sup&amp;gt; • … • p&amp;lt;sub&amp;gt;m&amp;lt;/sub&amp;gt;&amp;lt;sup&amp;gt;k&amp;lt;sub&amp;gt;m&amp;lt;/sub&amp;gt;&amp;lt;/sup&amp;gt;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
atunci multiplicitatea (exponentul) lui &amp;#039;&amp;#039;a&amp;#039;&amp;#039; în &amp;#039;&amp;#039;n&amp;#039;&amp;#039;&amp;lt;nowiki&amp;gt;!&amp;lt;/nowiki&amp;gt; este&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;Exp(a,n!) = min(Exp(p_1^{k_1},n!),Exp(p_2^{k_2},n!),\ldots,Exp(p_m^{k_m},n!))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
sau&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;Exp(a,n!) = min(\frac{Exp(p_1,n!)}{k_1},\frac{Exp(p_2,n!)}{k_2},\ldots,\frac{Exp(p_m,n!)}{k_m})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Memoizare ==&lt;br /&gt;
&amp;#039;&amp;#039;Memoizarea&amp;#039;&amp;#039; este o metodă de a face un program mai rapid fără a-i schimba modul în care el funcționează. Ideea ei este ca atunci cînd efectuăm un calcul scump să păstrăm valoarea calculată într-un tablou pentru a economisi timp în cazul cînd în viitor vom avea din nou nevoie de acea valoare. Să o învățăm prin exemple.&lt;br /&gt;
=== Exemplu ===&lt;br /&gt;
Să presupunem că ni se dau &amp;#039;&amp;#039;n&amp;#039;&amp;#039; numere &amp;#039;&amp;#039;a&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt;, a&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;, ..., a&amp;lt;sub&amp;gt;n-1&amp;lt;/sub&amp;gt;&amp;#039;&amp;#039; și ni se cere să afișăm factorialele acelor numere modulo &amp;#039;&amp;#039;k&amp;#039;&amp;#039;. O soluție naivă ar putea fi următoarea:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;for ( i = 0; i &amp;lt; n; i++ ) {&lt;br /&gt;
  p = 1;&lt;br /&gt;
  for ( j = 2; j &amp;lt; a[i]; j++ )&lt;br /&gt;
    p = (p * j) % k;&lt;br /&gt;
  printf( &amp;quot;%d &amp;quot;, p );&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Să calculăm complexitatea tipului de execuție: pentru fiecare număr &amp;#039;&amp;#039;a&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;&amp;#039;&amp;#039; vom face &amp;#039;&amp;#039;O(a&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;)&amp;#039;&amp;#039; înmulțiri, drept pentru care complexitatea soluției este &amp;#039;&amp;#039;O(suma(a&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;))&amp;#039;&amp;#039;. Desigur că putem face un program mai eficient care calculează un vector &amp;lt;tt&amp;gt;fact[i]&amp;lt;/tt&amp;gt; unde &amp;lt;tt&amp;gt;fact[i]&amp;lt;/tt&amp;gt; este &amp;#039;&amp;#039;i&amp;#039;&amp;#039;! (&amp;#039;&amp;#039;i&amp;#039;&amp;#039; factorial). Acest vector se poate calcula în &amp;#039;&amp;#039;O(max(a&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;))&amp;#039;&amp;#039;, după care printr-o parcurgere a numerelor &amp;#039;&amp;#039;a&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;&amp;#039;&amp;#039; vom putea calcula rezultatul ceea ce duce la o complexitate optimă de &amp;#039;&amp;#039;O(n + max(a&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;))&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
Însă în unele cazuri nu este ușor să schimbăm radical programul pentru a scrie o soluție mai eficientă decît soluția naivă. Cum putem folosi tehnica &amp;#039;&amp;#039;memoizării&amp;#039;&amp;#039; pentru a modifica foarte puțin soluția brută și a o aduce la complexitate optimă? Am putea ca de fiecare dată cînd calculăm &amp;#039;&amp;#039;a&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;&amp;#039;&amp;#039;! să păstrăm rezultatul într-un vector la poziția &amp;#039;&amp;#039;a&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;&amp;#039;&amp;#039;. Vom păstra, de asemenea și toate factorialele intermediare calculate pe parcurs. Atunci cînd vom avea nevoie de calculul unui factorial vom merge în jos pînă la primul factorial calculat. Iată implementarea:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;fact[1] = 1; // pentru a ne opri la final&lt;br /&gt;
for ( i = 0; i &amp;lt; n; i++ ) {&lt;br /&gt;
  j = a[i];&lt;br /&gt;
  while ( fact[j] == 0 )      // cautam in jos primul factorial calculat&lt;br /&gt;
    j--;&lt;br /&gt;
  p = fact[j];&lt;br /&gt;
  for ( j++; j &amp;lt;= a[i]; j++ ) // calculam toate valorile pina la a[i]&lt;br /&gt;
    fact[j] = (fact[j-1] * j) % k;&lt;br /&gt;
  printf( &amp;quot;%d &amp;quot;, fact[j] );&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ce complexitate în timp are această soluție? Deoarece ea nu repetă calcule în vectorul &amp;lt;tt&amp;gt;fact&amp;lt;/tt&amp;gt; rezultă că fiecare element al vectorului va fi calculat cel mult odată, în timp &amp;#039;&amp;#039;O(1)&amp;#039;&amp;#039;, deci soluția va fi optimă, &amp;#039;&amp;#039;O(n+max(a&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;))&amp;#039;&amp;#039;. Observați că am obținut aceeași complexitate optimă dar fără a schimba structura algoritmului nostru naiv, ci doar memorînd rezultate parțiale într-un vector. Aceasta este exact ideea memoizării.&lt;br /&gt;
&lt;br /&gt;
== Funcții în limbajul C ==&lt;br /&gt;
Funcțiile permit programelor complicate să fie parcelate în blocuri mici, fiecare din ele fiind mai ușor de scris, citit și modificat (întreținut). Am întîlnit deja funcția &amp;lt;tt&amp;gt;main()&amp;lt;/tt&amp;gt; și am folosit funcții de intrare ieșire, precum și funcții matematice din bibliotecile standard. Vom vedea în continuare cum putem să scriem propriile noastre funcții.&lt;br /&gt;
&lt;br /&gt;
=== De ce funcții ===&lt;br /&gt;
* Pentru a nu repeta cod.&lt;br /&gt;
* Pentru organizare, citibilitate, ușurinta înțelegerii codului și întreținerea codului.&lt;br /&gt;
* Recursivitate, precum vom vedea anul următor.&lt;br /&gt;
&lt;br /&gt;
=== Sintaxa: cum scriem o funcție ===&lt;br /&gt;
==== Sintaxa (simplificare) ====&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;tip returnat&amp;gt; &amp;lt;nume funcție&amp;gt;(&amp;lt;tip1&amp;gt; &amp;lt;var1&amp;gt;, &amp;lt;tip2&amp;gt; &amp;lt;var2&amp;gt;, ..., &amp;lt;tipn&amp;gt; &amp;lt;varn&amp;gt;) {&lt;br /&gt;
  ... declarații variabile ...&lt;br /&gt;
  ... cod funcție ...&lt;br /&gt;
  return &amp;lt;valoare return&amp;gt;; // dacă tipul returnat nu este &amp;#039;void&amp;#039;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== Parametri și valoarea returnată ====&lt;br /&gt;
* Parametri, valoare returnată&lt;br /&gt;
* Transmisia parametrilor se face numai prin copiere, pe stiva sistem&lt;br /&gt;
** Ce afișează următorul program:&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;void inc( int a ) {&lt;br /&gt;
  a++;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
  int x = 0;&lt;br /&gt;
  inc( x );&lt;br /&gt;
  printf( &amp;quot;%d&amp;quot;, x );&lt;br /&gt;
  return 0;&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Valoarea returnată, prin copiere pe stiva sistem&lt;br /&gt;
* Cum modificam parametrii, operatorii &amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; si &amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt;; ar fi bine să evitați, deocamdată. Exemplu: functia swap.&lt;br /&gt;
* Transmisie vectori ca parametri; vom transmite și lungimea; vectorul și lungimea lui sînt componente inseparabile ale tipului de date abstract.&lt;br /&gt;
** Ce se întîmplă dacă modificăm elementele vectorului în funcție?&lt;br /&gt;
** Ce se întîmplă dacă modificăm lungimea vectorului în funcție?&lt;br /&gt;
* Declarații de variabile și vizibilitatea acestora. Așezarea lor pe stivă.&lt;br /&gt;
* Conversia de tip cînd chemăm funcția cu alte tipuri decît cele declarate.&lt;br /&gt;
&lt;br /&gt;
==== Apelul ====&lt;br /&gt;
O funcție este apelată astfel: &amp;lt;tt&amp;gt;numeFunctie( valoare1, valoare2, ..., valoaren );&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Tema =&lt;br /&gt;
* Implementați algoritmii din clasă la vianuarena: [http://varena.ro/problema/bitona bitonă], [http://varena.ro/problema/majoritar majoritar], [http://varena.ro/problema/selectie selecție]&lt;br /&gt;
* [http://varena.ro/runda/2014-09-30-clasa-7-tema-2 Tema 2 clasa a 7&amp;lt;sup&amp;gt;a&amp;lt;/sup&amp;gt;]&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Opţional:&amp;#039;&amp;#039;&amp;#039; Tema de la clasa a 8&amp;lt;sup&amp;gt;a&amp;lt;/sup&amp;gt;&lt;br /&gt;
Rezolvări aici [http://solpedia.francu.com/wiki/index.php/Clasa_VII/VIII_lec%C8%9Bia_2_-_30_sep_2014]&lt;br /&gt;
&lt;br /&gt;
= Lecția 3 - Recursivitate (extensie) =&lt;br /&gt;
&lt;br /&gt;
== Interclasarea a doi vectori prin recursivitate ==&lt;br /&gt;
&lt;br /&gt;
Dându-se 3 vectori:&lt;br /&gt;
* vectorul 1 prin pointeri către începutul și după sfârșitul lui;&lt;br /&gt;
* vectorul 2 prin pointeri către începutul și după sfârșitul lui;&lt;br /&gt;
* vectorul 3 printr-un pointer către începutul lui&lt;br /&gt;
și garantându-se că:&lt;br /&gt;
* elementele vectorilor 1 și 2 sunt în ordine crescătoare;&lt;br /&gt;
* vectorul 3 are rezervat un spațiu cel puțin egal cu suma lungimilor vectorilor 1 și 2,&lt;br /&gt;
să se scrie o funcție recursivă care primește ca parametri cei 3 vectori și îi interclasează pe primii 2 în al treilea.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
void interclaseaza(&lt;br /&gt;
        int* v1Inc, int* v1Sf,&lt;br /&gt;
        int* v2Inc, int* v2Sf,&lt;br /&gt;
        int* v3Inc) {&lt;br /&gt;
    if (v1Inc != v1Sf &amp;amp;&amp;amp; v2Inc != v2Sf) {&lt;br /&gt;
        if (*v1Inc &amp;lt; *v2Inc) {&lt;br /&gt;
            *v3Inc = *v1Inc;&lt;br /&gt;
            interclaseaza(v1Inc + 1, v1Sf, v2Inc, v2Sf, v3Inc + 1);&lt;br /&gt;
        } else {&lt;br /&gt;
            *v3Inc = *v2Inc;&lt;br /&gt;
            interclaseaza(v1Inc, v1Sf, v2Inc + 1, v2Sf, v3Inc + 1);&lt;br /&gt;
        }&lt;br /&gt;
    } else if (v1Inc != v1Sf) {&lt;br /&gt;
        *v3Inc = *v1Inc;&lt;br /&gt;
        interclaseaza(v1Inc + 1, v1Sf, v2Inc, v2Sf, v3Inc + 1);&lt;br /&gt;
    } else if (v2Inc != v2Sf) {&lt;br /&gt;
        *v3Inc = *v2Inc;&lt;br /&gt;
        interclaseaza(v1Inc, v1Sf, v2Inc + 1, v2Sf, v3Inc + 1);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Temă =&lt;br /&gt;
&lt;br /&gt;
Opțional: Să se rezolve cerința 2 din problema [http://varena.ro/problema/portofel Portofel] prin recursivitate.&lt;br /&gt;
&lt;br /&gt;
= BFS Continuare =&lt;br /&gt;
&lt;br /&gt;
== Problema Alee ==&lt;br /&gt;
&lt;br /&gt;
=== Cu reconstituirea drumului ===&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define MAX_N 175&lt;br /&gt;
&lt;br /&gt;
int mat[1 + MAX_N + 1][1 + MAX_N + 1];&lt;br /&gt;
int dist[1 + MAX_N + 1][1 + MAX_N + 1];&lt;br /&gt;
&lt;br /&gt;
// doar primele 4 directii sunt folosite&lt;br /&gt;
int dirLin[] = { 1, -1,  0,  0,  1,  1, -1, -1};&lt;br /&gt;
int dirCol[] = { 0,  0,  1, -1,  1, -1,  1, -1};&lt;br /&gt;
&lt;br /&gt;
int linie[MAX_N * MAX_N];&lt;br /&gt;
int coloana[MAX_N * MAX_N];&lt;br /&gt;
int inceput, sfarsit;&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  FILE* in = fopen(&amp;quot;alee.in&amp;quot;, &amp;quot;r&amp;quot;);&lt;br /&gt;
  FILE* out = fopen(&amp;quot;alee.out&amp;quot;, &amp;quot;w&amp;quot;);&lt;br /&gt;
  int N, M;&lt;br /&gt;
  int i, j;&lt;br /&gt;
  int l, c;&lt;br /&gt;
&lt;br /&gt;
  // citirea datelor&lt;br /&gt;
  fscanf(in, &amp;quot;%d %d&amp;quot;, &amp;amp;N, &amp;amp;M);&lt;br /&gt;
  for (i = 0; i &amp;lt; M; ++i) {&lt;br /&gt;
    fscanf(in, &amp;quot;%d %d&amp;quot;, &amp;amp;l, &amp;amp;c);&lt;br /&gt;
    mat[l][c] = 1; // obstacol&lt;br /&gt;
  }&lt;br /&gt;
  int L1, C1, L2, C2;&lt;br /&gt;
  fscanf(in, &amp;quot;%d %d&amp;quot;, &amp;amp;L1, &amp;amp;C1);&lt;br /&gt;
  fscanf(in, &amp;quot;%d %d&amp;quot;, &amp;amp;L2, &amp;amp;C2);&lt;br /&gt;
  // bordarea matricei&lt;br /&gt;
  for (c = 0; c &amp;lt;= N + 1; c++) {&lt;br /&gt;
	  mat[0][c] = 1;&lt;br /&gt;
	  mat[N + 1][c] = 1;&lt;br /&gt;
  }&lt;br /&gt;
  for (l = 1; l &amp;lt;= N; l++) {&lt;br /&gt;
	  mat[l][0] = 1;&lt;br /&gt;
	  mat[l][N + 1] = 1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // calcularea solutiei&lt;br /&gt;
  for (i = 0; i &amp;lt;= N + 1; ++i) {&lt;br /&gt;
    for (j = 0; j &amp;lt;= N + 1; ++j) {&lt;br /&gt;
      dist[i][j] = 0;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  dist[L1][C1] = 1;&lt;br /&gt;
  int vechi = 0;&lt;br /&gt;
  inceput = sfarsit = 0;&lt;br /&gt;
  linie[sfarsit] = L1;&lt;br /&gt;
  coloana[sfarsit] = C1;&lt;br /&gt;
  sfarsit++;&lt;br /&gt;
  while (inceput &amp;lt; sfarsit &amp;amp;&amp;amp; dist[L2][C2] == 0) {&lt;br /&gt;
    l = linie[inceput];&lt;br /&gt;
    c = coloana[inceput];&lt;br /&gt;
    inceput++;&lt;br /&gt;
    for (i = 0; i &amp;lt; 4; ++i) {&lt;br /&gt;
      if (mat[l + dirLin[i]][c + dirCol[i]] == 0 &amp;amp;&amp;amp; dist[l + dirLin[i]][c + dirCol[i]] == 0) {&lt;br /&gt;
	    dist[l + dirLin[i]][c + dirCol[i]] = dist[l][c] + 1;&lt;br /&gt;
	    linie[sfarsit] = l + dirLin[i];&lt;br /&gt;
	    coloana[sfarsit] = c + dirCol[i];&lt;br /&gt;
	    sfarsit++;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    ++vechi;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // afisarea solutiei&lt;br /&gt;
  fprintf(out, &amp;quot;%d\n&amp;quot;, dist[L2][C2]);&lt;br /&gt;
&lt;br /&gt;
  // reconstituirea drumului&lt;br /&gt;
  l = L2;&lt;br /&gt;
  c = C2;&lt;br /&gt;
  fprintf(out, &amp;quot;%d %d\n&amp;quot;, l, c);&lt;br /&gt;
  for (j = dist[l][c]; j &amp;gt; 1; j--) {&lt;br /&gt;
    assert(dist[l][c] == j);&lt;br /&gt;
    i = 0;&lt;br /&gt;
    while (dist[l + dirLin[i]][c + dirCol[i]] != dist[l][c] - 1) {&lt;br /&gt;
      // Conditia i &amp;lt; 4 nu este necesara deoarece tot timpul&lt;br /&gt;
      // va exista cel putin un vecin.&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    l = l + dirLin[i];&lt;br /&gt;
    c = c + dirCol[i];&lt;br /&gt;
    fprintf(out, &amp;quot;%d %d\n&amp;quot;, l, c);&lt;br /&gt;
  }&lt;br /&gt;
  fclose(in);&lt;br /&gt;
  fclose(out);&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Cu operații specifice structurii coadă ===&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
#include &amp;lt;assert.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define MAX_N 175&lt;br /&gt;
&lt;br /&gt;
int mat[1 + MAX_N + 1][1 + MAX_N + 1];&lt;br /&gt;
int dist[1 + MAX_N + 1][1 + MAX_N + 1];&lt;br /&gt;
&lt;br /&gt;
// doar primele 4 directii sunt folosite&lt;br /&gt;
int dirLin[] = { 1, -1,  0,  0,  1,  1, -1, -1};&lt;br /&gt;
int dirCol[] = { 0,  0,  1, -1,  1, -1,  1, -1};&lt;br /&gt;
&lt;br /&gt;
int linie[MAX_N * MAX_N];&lt;br /&gt;
int coloana[MAX_N * MAX_N];&lt;br /&gt;
int inceput, sfarsit;&lt;br /&gt;
&lt;br /&gt;
void push(int l, int c) {&lt;br /&gt;
	linie[sfarsit] = l;&lt;br /&gt;
	coloana[sfarsit] = c;&lt;br /&gt;
	sfarsit++;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int topL() {&lt;br /&gt;
	return linie[inceput % SIZE];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int topC() {&lt;br /&gt;
	return coloana[inceput % SIZE];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void pop() {&lt;br /&gt;
	inceput++;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int isEmpty() {&lt;br /&gt;
	return inceput == sfarsit;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int size() {&lt;br /&gt;
	return sfarsit - inceput;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
  FILE* in = fopen(&amp;quot;alee.in&amp;quot;, &amp;quot;r&amp;quot;);&lt;br /&gt;
  FILE* out = fopen(&amp;quot;alee.out&amp;quot;, &amp;quot;w&amp;quot;);&lt;br /&gt;
  int N, M;&lt;br /&gt;
  int i, j;&lt;br /&gt;
  int l, c;&lt;br /&gt;
&lt;br /&gt;
  // citirea datelor&lt;br /&gt;
  fscanf(in, &amp;quot;%d %d&amp;quot;, &amp;amp;N, &amp;amp;M);&lt;br /&gt;
  for (i = 0; i &amp;lt; M; ++i) {&lt;br /&gt;
    fscanf(in, &amp;quot;%d %d&amp;quot;, &amp;amp;l, &amp;amp;c);&lt;br /&gt;
    mat[l][c] = 1; // obstacol&lt;br /&gt;
  }&lt;br /&gt;
  int L1, C1, L2, C2;&lt;br /&gt;
  fscanf(in, &amp;quot;%d %d&amp;quot;, &amp;amp;L1, &amp;amp;C1);&lt;br /&gt;
  fscanf(in, &amp;quot;%d %d&amp;quot;, &amp;amp;L2, &amp;amp;C2);&lt;br /&gt;
  for (c = 0; c &amp;lt;= N + 1; c++) {&lt;br /&gt;
	  mat[0][c] = 1;&lt;br /&gt;
	  mat[N + 1][c] = 1;&lt;br /&gt;
  }&lt;br /&gt;
  for (l = 1; l &amp;lt;= N; l++) {&lt;br /&gt;
	  mat[l][0] = 1;&lt;br /&gt;
	  mat[l][N + 1] = 1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // calcularea solutiei&lt;br /&gt;
  for (i = 0; i &amp;lt;= N + 1; ++i) {&lt;br /&gt;
    for (j = 0; j &amp;lt;= N + 1; ++j) {&lt;br /&gt;
      dist[i][j] = 0;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  dist[L1][C1] = 1;&lt;br /&gt;
  int vechi = 0;&lt;br /&gt;
  inceput = sfarsit = 0;&lt;br /&gt;
  linie[sfarsit] = L1;&lt;br /&gt;
  coloana[sfarsit] = C1;&lt;br /&gt;
  sfarsit++;&lt;br /&gt;
  while (!isEmpty() &amp;amp;&amp;amp; dist[L2][C2] == 0) {&lt;br /&gt;
    l = topL();&lt;br /&gt;
    c = topC();&lt;br /&gt;
    pop();&lt;br /&gt;
    for (i = 0; i &amp;lt; 4; ++i) {&lt;br /&gt;
      if (mat[l + dirLin[i]][c + dirCol[i]] == 0 &amp;amp;&amp;amp; dist[l + dirLin[i]][c + dirCol[i]] == 0) {&lt;br /&gt;
	    dist[l + dirLin[i]][c + dirCol[i]] = dist[l][c] + 1;&lt;br /&gt;
	    push(l + dirLin[i], c + dirCol[i]);&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    ++vechi;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // afisarea solutiei&lt;br /&gt;
  fprintf(out, &amp;quot;%d\n&amp;quot;, dist[L2][C2]);&lt;br /&gt;
&lt;br /&gt;
  // reconstituirea drumului&lt;br /&gt;
  l = L2;&lt;br /&gt;
  c = C2;&lt;br /&gt;
  fprintf(out, &amp;quot;%d %d\n&amp;quot;, l, c);&lt;br /&gt;
  for (j = dist[l][c]; j &amp;gt; 1; j--) {&lt;br /&gt;
    assert(dist[l][c] == j);&lt;br /&gt;
    i = 0;&lt;br /&gt;
    while (dist[l + dirLin[i]][c + dirCol[i]] != dist[l][c] - 1) {&lt;br /&gt;
      // Conditia i &amp;lt; 4 nu este necesara deoarece tot timpul&lt;br /&gt;
      // va exista cel putin un vecin.&lt;br /&gt;
      i++;&lt;br /&gt;
    }&lt;br /&gt;
    l = l + dirLin[i];&lt;br /&gt;
    c = c + dirCol[i];&lt;br /&gt;
    fprintf(out, &amp;quot;%d %d\n&amp;quot;, l, c);&lt;br /&gt;
  }&lt;br /&gt;
  fclose(in);&lt;br /&gt;
  fclose(out);&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Cu coadă implementată circular ===&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
#define SIZE (2 * (MAX_N + MAX_N))&lt;br /&gt;
&lt;br /&gt;
int linie[SIZE];&lt;br /&gt;
int coloana[SIZE];&lt;br /&gt;
int inceput, sfarsit;&lt;br /&gt;
&lt;br /&gt;
void push(int l, int c) {&lt;br /&gt;
	linie[sfarsit % SIZE] = l;&lt;br /&gt;
	coloana[sfarsit % SIZE] = c;&lt;br /&gt;
	sfarsit++;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int topL() {&lt;br /&gt;
	return linie[inceput % SIZE];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int topC() {&lt;br /&gt;
	return coloana[inceput % SIZE];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void pop() {&lt;br /&gt;
	inceput++;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int isEmpty() {&lt;br /&gt;
	return inceput == sfarsit;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int size() {&lt;br /&gt;
	return sfarsit - inceput;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Dan</name></author>
	</entry>
</feed>