Advertisement
OvidiuF

Misionari si canibali

Mar 23rd, 2018
185
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.92 KB | None | 0 0
  1. #pragma warning(disable:4996)
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <conio.h>
  5.  
  6. struct alfabet {
  7. int m, c, b;
  8. };
  9. struct alfabet noduri[20], nod, Vizitate[20], parinte[20], solutie[20];
  10.  
  11. bool conditie_vizitate(int nr_vizitate, struct alfabet aux) { // Testeaza daca dupa mutarea respectiva s-a ajuns la o stare anterioara
  12. for (int i = 0; i < nr_vizitate; i++)
  13. if (aux.b == 0) { // daca suntem pe primul mal
  14. if ((aux.m == Vizitate[i].m) && (aux.c == Vizitate[i].c) && (aux.b == Vizitate[i].b))
  15. return false;
  16. }
  17. else // daca suntem pe al doilea mal
  18. if ((3 - aux.m == Vizitate[i].m) && (3 - aux.c == Vizitate[i].c) && (aux.b == Vizitate[i].b))
  19. return false;
  20. return true;
  21. }
  22.  
  23. bool conditii_necesare(int nr_vizitate, struct alfabet aux) { // Testeaza daca se poate face mutarea respecti
  24. // Primele doua conditii pe primul mal sa fie mai multi misionari decat canibali sau sa nu fie niciun misionar
  25. // A treia si a patra conditie sa avem mai multi misionari si canibali decat 0dupa mutarea respectiva se verifica daca s-a ajuns la o stare anterioara
  26. // A cincea conditie dupa mutarea respectiva se verifica daca s-a ajuns la o stare anterioara
  27. // A sasea si saptea conditie pe malul opus sa avem mai multi misionari decat canibali sau sa nu avem niciun misionar
  28. // A opta si a noua conditie pe malul opus sa avem mai multi misionari si canibali decat 0
  29. if (((aux.m >= aux.c) || (aux.m == 0)) && (aux.m >= 0) && (aux.c >= 0) && (conditie_vizitate(nr_vizitate, aux) == true) &&
  30. ((3 - aux.m >= 3 - aux.c) || (3 - aux.m == 0)) && ((3 - aux.m >= 0) && (3 - aux.c >= 0)))
  31. return true;
  32. return false;
  33. }
  34.  
  35. void adaugare_in_noduri(struct alfabet aux, int &nr_noduri, int &nr_vizitate) { // Daca se poate face mutarea respectiva se adauga in noduri si in Vizitate si se retine parintele
  36. if (aux.b == 0) { // daca suntem pe primul mal
  37. Vizitate[nr_vizitate++] = noduri[nr_noduri++] = aux;
  38. }
  39. else { // daca suntem pe al doilea mal
  40. Vizitate[nr_vizitate].m = noduri[nr_noduri].m = 3 - aux.m;
  41. Vizitate[nr_vizitate].c = noduri[nr_noduri].c = 3 - aux.c;
  42. Vizitate[nr_vizitate++].b = noduri[nr_noduri++].b = 1;
  43. }
  44. parinte[nr_vizitate - 1] = nod;
  45. }
  46.  
  47. void afisare_mutare_urmatoare(int i) { // Pentru a afisa mutarile pe care le face algoritmul la final
  48. if (((solutie[i - 1].m - 1 == solutie[i].m) &&
  49. (solutie[i - 1].c - 1 == solutie[i].c)) || ((solutie[i - 1].m + 1 == solutie[i].m) &&
  50. (solutie[i - 1].c + 1 == solutie[i].c)))
  51. printf("1misionar si 1canibal");
  52. if (((solutie[i - 1].m - 1 == solutie[i].m) || (solutie[i - 1].m + 1 == solutie[i].m)) &&
  53. (solutie[i - 1].c == solutie[i].c))
  54. printf("1misionar");
  55. if (((solutie[i - 1].m - 2 == solutie[i].m) || (solutie[i - 1].m + 2 == solutie[i].m)) &&
  56. (solutie[i - 1].c == solutie[i].c))
  57. printf("2misionari");
  58. if (((solutie[i - 1].c - 1 == solutie[i].c) || (solutie[i - 1].c + 1 == solutie[i].c)) &&
  59. (solutie[i - 1].m == solutie[i].m))
  60. printf("1canibal");
  61. if (((solutie[i - 1].c - 2 == solutie[i].c) || (solutie[i - 1].c + 2 == solutie[i].c)) &&
  62. (solutie[i - 1].m == solutie[i].m))
  63. printf("2canibali");
  64. }
  65. void rezolva() {
  66. int sol = 0, nr_noduri = 0, nr_vizitate = 0, barca, nr_parinte = 0;
  67.  
  68. Vizitate[0].m = Vizitate[0].c = 3; // Initializarea datelor initiale in noduri si Vizitate cu 3m 3c 1
  69. Vizitate[nr_vizitate++].b = 1;
  70. noduri[nr_noduri].m = noduri[nr_noduri].c = 3;
  71. noduri[nr_noduri++].b = 1;
  72. while (sol == 0) {
  73. nod = noduri[0];
  74. barca = nod.b;
  75. for (int i = 1; i < nr_noduri; i++)
  76. noduri[i - 1] = noduri[i];
  77. nr_noduri--;
  78. if ((nod.m == 0) && (nod.c == 0) && (nod.b == 0))
  79. sol = 1;
  80. else {
  81. struct alfabet aux = nod;
  82. if (barca == 1) // Daca barca=1 suntem pe primul mal, daca barca=0 suntem pe al doilea mal
  83. aux.b = 0;
  84. else
  85. aux.b = 1;
  86. if (aux.b == 1) { // Daca suntem pe al doilea mal dam valorile de pe malul respectiv ex: (3,2,0) inseamna ca pe malul al doilea avem 3-3=0m 3-2=1c (0,1,0)
  87. aux.m = 3 - aux.m;
  88. aux.c = 3 - aux.c;
  89. }
  90. aux.m--;
  91. if (conditii_necesare(nr_vizitate, aux) == true) // Se testeaza daca se poate muta 1m
  92. adaugare_in_noduri(aux, nr_noduri, nr_vizitate); // Se adauga in noduri si Vizitat situatia dupa mutare
  93.  
  94. aux.m++;
  95. aux.m = aux.m - 2;
  96. if (conditii_necesare(nr_vizitate, aux) == true) // Se testeaza daca se pot muta 2m
  97. adaugare_in_noduri(aux, nr_noduri, nr_vizitate);
  98.  
  99. aux.m = aux.m + 2;
  100. aux.c--;
  101. if (conditii_necesare(nr_vizitate, aux) == true) // Se testeaza daca se poate muta 1c
  102. adaugare_in_noduri(aux, nr_noduri, nr_vizitate);
  103.  
  104. aux.c++;
  105. aux.c = aux.c - 2;
  106. if (conditii_necesare(nr_vizitate, aux) == true) // Se testeaza daca se pot muta 2c
  107. adaugare_in_noduri(aux, nr_noduri, nr_vizitate);
  108.  
  109. aux.c = aux.c + 2;
  110. aux.c--;
  111. aux.m--;
  112. if (conditii_necesare(nr_vizitate, aux) == true) // Se testeaza daca se poate muta 1m si 1c
  113. adaugare_in_noduri(aux, nr_noduri, nr_vizitate);
  114. }
  115. }
  116.  
  117. int n = 0;
  118.  
  119. solutie[n++] = Vizitate[nr_vizitate - 1]; // Initializam solutia cu (0,0,0)
  120. while ((solutie[n - 1].m != 3) || (solutie[n - 1].c != 3) || (solutie[n - 1].b != 1)) { // Parcurgem in mod invers de la final la inceput
  121. int i = 0;
  122. while ((solutie[n - 1].m != Vizitate[i].m) || (solutie[n - 1].c != Vizitate[i].c) || (solutie[n - 1].b != Vizitate[i].b)) // Cautam parintele nodului solutie[n-1]
  123. i++;
  124. solutie[n++] = parinte[i]; // Introducem parintele in solutie si continuam pana ajungem la inceput( (3,3,1) )
  125. }
  126. for (int i = n - 1; i >= 0; i--) { // Afisam solutia
  127. printf("Starea curenta: (%dm,%dc,%d) \n", solutie[i].m, solutie[i].c, solutie[i].b);
  128. printf("Mutarea urmatoare: ");
  129. afisare_mutare_urmatoare(i);
  130. printf("\n\n");
  131. }
  132. }
  133.  
  134. void main() {
  135.  
  136. rezolva();
  137. _getch();
  138. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement