Guest User

Untitled

a guest
Feb 21st, 2018
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.47 KB | None | 0 0
  1. //
  2. // Canibais.cpp
  3. // Canibais e Missionarios
  4. //
  5. // Created by Edvaldo Junior on 08/02/2018.
  6. // Copyright © 2018 Edvaldo Junior. All rights reserved.
  7. //
  8. // No problema dos canibais e missionários, três missionários e três canibais devem atravessar um rio
  9. // com um barco que pode transportar no máximo duas pessoas, sob a restrição de que, para ambas as
  10. // margens, se há missionários presentes naquela margem, eles não podem ser ultrapassados pelo número
  11. // de canibais na mesma margem (se fossem, os canibais comeriam os missionários.) O barco não pode
  12. // atravessar o rio por si só, sem pessoas a bordo.
  13. //
  14. // O programa resolve o problema de forma geral (para qualquer número nao negativo de missionarios e
  15. // canibais, além de qualquer número de pessoas suportadas pelo barco). Basta que as constantes
  16. // MAXMISSIONARIOS, MAXCANIBAIS e MAXBARCO sejam alteradas.
  17. //
  18.  
  19. #include <bits/stdc++.h>
  20.  
  21. using namespace std;
  22.  
  23. #define canibais first
  24. #define missionarios second
  25. #define lado1 first.first
  26. #define lado2 first.second
  27. #define noLado1 true
  28. #define noLado2 false
  29. #define ladoDoBarco second
  30. #define MAXMISSIONARIOS 3
  31. #define MAXCANIBAIS 3
  32. #define MAXBARCO 2
  33.  
  34. typedef pair<int, int> LadoDoRio;
  35. typedef pair<pair<LadoDoRio, LadoDoRio>, bool> Situacao;
  36.  
  37. bool visitados[MAXCANIBAIS + 1][MAXMISSIONARIOS + 1][MAXCANIBAIS + 1][MAXMISSIONARIOS + 1][2];
  38. int distancia[MAXCANIBAIS + 1][MAXMISSIONARIOS + 1][MAXCANIBAIS + 1][MAXMISSIONARIOS + 1][2];
  39. Situacao pais[MAXCANIBAIS + 1][MAXMISSIONARIOS + 1][MAXCANIBAIS + 1][MAXMISSIONARIOS + 1][2];
  40.  
  41. void iniciaMatrizes();
  42. void buscaSolucao(Situacao, Situacao);
  43. void valores(Situacao, int[4]);
  44. void mostra(Situacao);
  45. void visita(int[4], bool);
  46. void alcancadasPor(Situacao, vector<Situacao>&);
  47. void marcaDistancia(int[4], bool, int);
  48. void marcaPai(int[4], bool, Situacao);
  49. void organizaSolucao(Situacao, Situacao, stack<Situacao>&);
  50. void mostraSolucao(stack<Situacao>);
  51. bool permitido(LadoDoRio);
  52. bool permitido(Situacao);
  53. bool visitou(int[4], bool);
  54. int pegaDistancia(int[4], bool);
  55. Situacao pegaPai(int[4], bool);
  56.  
  57. int main () {
  58.  
  59. LadoDoRio l1(MAXCANIBAIS, MAXMISSIONARIOS), l2(0, 0),
  60. idealLado1(0, 0), idealLado2(MAXCANIBAIS, MAXMISSIONARIOS);
  61. Situacao inicial(make_pair(l1, l2), noLado1),
  62. ideal(make_pair(idealLado1, idealLado2), noLado2);
  63.  
  64. iniciaMatrizes();
  65. buscaSolucao(inicial, ideal);
  66.  
  67. int val[4];
  68. valores(ideal, val);
  69. int d = pegaDistancia(val, ideal.ladoDoBarco);
  70. if (d != INT_MAX) {
  71. stack<Situacao> pilha;
  72. organizaSolucao(inicial, ideal, pilha);
  73. mostraSolucao(pilha);
  74. } else { printf("Nao ha solucao!\n"); }
  75.  
  76. return 0;
  77. }
  78.  
  79. void iniciaMatrizes() {
  80.  
  81. for (int i = 0; i < MAXCANIBAIS + 1; ++i)
  82. for (int j = 0; j < MAXMISSIONARIOS + 1; j++)
  83. for (int k = 0; k < MAXCANIBAIS + 1; k++)
  84. for (int l = 0; l < MAXMISSIONARIOS + 1; l++)
  85. for (int m = 0; m < 2; m++) {
  86. LadoDoRio l1(-1, -1), l2(-1, -1);
  87. Situacao s(make_pair(l1, l2), noLado1);
  88. visitados[i][j][k][l][m] = false;
  89. distancia[i][j][k][l][m] = INT_MAX;
  90. pais[i][j][k][l][m] = s;
  91. }
  92. }
  93.  
  94. void buscaSolucao(Situacao inicial, Situacao ideal) {
  95.  
  96. queue<Situacao> fila;
  97. fila.push(inicial);
  98. int val[4];
  99. valores(inicial, val);
  100. visita(val, inicial.ladoDoBarco);
  101. marcaDistancia(val, inicial.ladoDoBarco, 0);
  102. marcaPai(val, inicial.ladoDoBarco, inicial);
  103.  
  104. while (!fila.empty()) {
  105. Situacao atual = fila.front();
  106. fila.pop();
  107. valores(atual, val);
  108. int distanciaA = pegaDistancia(val, atual.ladoDoBarco);
  109.  
  110. if (atual == ideal) {
  111. printf("Conseguiu em %d passos\n", distanciaA);
  112. break;
  113. }
  114. vector<Situacao> alcancadas;
  115. alcancadasPor(atual, alcancadas);
  116. visita(val, atual.ladoDoBarco);
  117.  
  118. for (auto s : alcancadas) {
  119. valores(s, val);
  120. int distanciaS = pegaDistancia(val, s.ladoDoBarco);
  121. if (!visitou(val, s.ladoDoBarco) && distanciaA + 1 < distanciaS) {
  122. fila.push(s);
  123. valores(s, val);
  124. marcaDistancia(val, s.ladoDoBarco, distanciaA + 1);
  125. marcaPai(val, s.ladoDoBarco, atual);
  126. }
  127. }
  128. }
  129. }
  130.  
  131. void valores(Situacao situacao, int val[4]) {
  132.  
  133. val[0] = situacao.lado1.canibais;
  134. val[1] = situacao.lado1.missionarios;
  135. val[2] = situacao.lado2.canibais;
  136. val[3] = situacao.lado2.missionarios;
  137. }
  138.  
  139. void visita(int valores[4], bool lado) {
  140.  
  141. int i = lado == noLado1 ? 1 : 0;
  142. visitados[valores[0]][valores[1]][valores[2]][valores[3]][i] = true;
  143. }
  144.  
  145. void marcaDistancia(int valores[4], bool lado, int valor) {
  146.  
  147. int i = lado == noLado1 ? 1 : 0;
  148. distancia[valores[0]][valores[1]][valores[2]][valores[3]][i] = valor;
  149. }
  150.  
  151. int pegaDistancia(int valores[4], bool lado) {
  152.  
  153. int i = lado == noLado1 ? 1 : 0;
  154. return distancia[valores[0]][valores[1]][valores[2]][valores[3]][i];
  155. }
  156.  
  157. void marcaPai(int valores[4], bool lado, Situacao pai) {
  158.  
  159. int i = lado == noLado1 ? 1 : 0;
  160. pais[valores[0]][valores[1]][valores[2]][valores[3]][i] = pai;
  161. }
  162.  
  163. void mostra(Situacao situacao) {
  164.  
  165. int v[4];
  166. valores(situacao, v);
  167. int d = pegaDistancia(v, situacao.ladoDoBarco);
  168. printf("%12s lado1 lado2 barco passo\n", " ");
  169. printf(" canibais: %d %d %s %d\n", v[0], v[2], situacao.ladoDoBarco == noLado1 ?
  170. "lado1" : "lado2", d);
  171. printf("missionarios: %d %d \n", v[1], v[3]);
  172. printf("\n");
  173. }
  174.  
  175. void alcancadasPor(Situacao situacao, vector<Situacao>& v) {
  176.  
  177. for (int i = 0; i <= MAXBARCO; i++)
  178. for (int j = 0; j <= MAXBARCO; j++)
  179. if (i + j > 0 && i + j <= MAXBARCO) {
  180. LadoDoRio l1(0, 0), l2(0, 0);
  181. int a = i, b = j;
  182. Situacao nova(make_pair(l1, l2), noLado1);
  183. if (situacao.ladoDoBarco == noLado2) {
  184. a *= -1;
  185. b *= -1;
  186. }
  187. nova.lado1.missionarios = situacao.lado1.missionarios - a;
  188. nova.lado1.canibais = situacao.lado1.canibais - b;
  189. nova.lado2.missionarios = situacao.lado2.missionarios + a;
  190. nova.lado2.canibais = situacao.lado2.canibais + b;
  191. nova.ladoDoBarco = !situacao.ladoDoBarco;
  192. if (permitido(nova)) { v.push_back(nova); }
  193. }
  194. }
  195.  
  196. bool permitido(LadoDoRio lado) {
  197.  
  198. return lado.missionarios == 0 ||
  199. (lado.missionarios >= lado.canibais &&
  200. lado.missionarios >= 0 && lado.canibais >= 0 &&
  201. lado.missionarios <= MAXMISSIONARIOS &&
  202. lado.canibais <= MAXCANIBAIS);
  203. }
  204.  
  205. bool permitido(Situacao situacao) {
  206. return permitido(situacao.lado1) && permitido(situacao.lado2);
  207. }
  208.  
  209. bool visitou(int valores[4], bool lado) {
  210.  
  211. int i = lado == noLado1 ? 1 : 0;
  212. return visitados[valores[0]][valores[1]][valores[2]][valores[3]][i];
  213. }
  214.  
  215. Situacao pegaPai(int valores[4], bool lado) {
  216.  
  217. int i = lado == noLado1 ? 1 : 0;
  218. return pais[valores[0]][valores[1]][valores[2]][valores[3]][i];
  219. }
  220.  
  221. void organizaSolucao(Situacao inicial, Situacao final, stack<Situacao>& pilha) {
  222.  
  223. Situacao atual = final;
  224.  
  225. while (atual != inicial) {
  226. pilha.push(atual);
  227. int val[4];
  228. valores(atual, val);
  229. atual = pegaPai(val, atual.ladoDoBarco);
  230. }
  231. pilha.push(atual);
  232. }
  233.  
  234. void mostraSolucao(stack<Situacao> pilha) {
  235.  
  236. while (!pilha.empty()) {
  237. Situacao s = pilha.top();
  238. pilha.pop();
  239. mostra(s);
  240. }
  241. }
Add Comment
Please, Sign In to add comment