Advertisement
a53

InfoOltenia_PB_wow

a53
Feb 21st, 2017
175
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.38 KB | None | 0 0
  1. /**
  2. Problema: wow
  3. Solutie: Algoritmul lui Lee pentru fiecare punct de plecare. Suma de distanta.
  4. Autor: Robert Hasna
  5. */
  6. #include <cstdio>
  7. #include <vector>
  8. #include <utility>
  9. #include <queue>
  10.  
  11. using namespace std;
  12.  
  13. typedef pair<int,int> Punct;
  14.  
  15. static const int NMAX = 100;
  16. static const int dx[] = { 0, 1, 0, -1 };
  17. static const int dy[] = { 1, 0, -1, 0 };
  18.  
  19. int N, M; // Latura labirintului
  20. int nr_pers; // Numarul de persoane
  21. int labirint[ NMAX ][ NMAX ]; // Labirintul
  22. int drumuri[ NMAX ][ NMAX ]; // Suma drumurilor
  23. int vizitat[ NMAX ][ NMAX ]; // Matrice de locuri vizitate, pentru Lee
  24. int vizitatTotal[ NMAX ][ NMAX ]; // Matrice in care stochez de cate ori a fost vizitat un punct in total.
  25. vector< Punct > oameni;
  26. queue< pair<Punct,int> > Q; // Coada pentru Lee. Punctul vizitat si costul de a ajunge la el
  27.  
  28. // Curata matricea de vizite. Pregatire pentru urmatoarea rulare a algoritmului lui lee.
  29. void stergeVizite() {
  30. for (int i = 0; i < N; ++i) {
  31. for (int j = 0; j < M; ++j) {
  32. vizitat[i][j] = 0;
  33. }
  34. }
  35. }
  36.  
  37. // Verifica daca un punct este in interiorul labirintului
  38. inline bool inLabirint(Punct punct) {
  39. return !(punct.first < 0 || punct.first >= N || punct.second < 0 || punct.second >= M);
  40. }
  41.  
  42. // Face un pas in algoritmul lui Lee. Primeste un puct si viziteaza toate cele 4 puncte adiacente.
  43. inline void pas(Punct punct, int cost) {
  44. for (int i = 0; i < 4; ++i) {
  45. Punct punctNou = make_pair(punct.first + dx[i], punct.second + dy[i]);
  46. if (inLabirint(punctNou) && !vizitat[punctNou.first][punctNou.second] && labirint[punctNou.first][punctNou.second] == 0) {
  47. vizitat[punctNou.first][punctNou.second] = 1;
  48. vizitatTotal[punctNou.first][punctNou.second]++;
  49. drumuri[punctNou.first][punctNou.second]+= cost + 1;
  50. Q.push(make_pair(punctNou, cost + 1));
  51. }
  52. }
  53. }
  54.  
  55. // Algoritmul lui lee
  56. void lee(Punct start) {
  57. stergeVizite();
  58. while(!Q.empty()) {
  59. Q.pop();
  60. }
  61. Q.push(make_pair(start, 0));
  62. vizitat[start.first][start.second] = 1;
  63. vizitatTotal[start.first][start.second]++;
  64.  
  65. while (!Q.empty()) {
  66. pair< Punct, int > q = Q.front();
  67. Q.pop();
  68. pas(q.first, q.second);
  69. }
  70. }
  71.  
  72. int main() {
  73. freopen("wow.in", "r", stdin);
  74. freopen("wow.out", "w", stdout);
  75.  
  76. // Citirea datelor
  77. scanf("%d %d %d\n", &N, &M, &nr_pers);
  78. for (int i = 0; i < N; ++i) {
  79. for (int j = 0; j < M; ++j) {
  80. scanf("%d", &labirint[i][j]);
  81. }
  82. }
  83.  
  84. for (int i = 0; i < nr_pers; ++i) {
  85. int x, y;
  86. scanf("%d %d", &x, &y);
  87. oameni.push_back(make_pair(x, y));
  88. }
  89.  
  90. // Rularea algoritmului lui Lee pentru fiecare om din labirint
  91. for (vector<Punct>::iterator it = oameni.begin(); it != oameni.end(); it++) {
  92. lee(*it);
  93. }
  94.  
  95. // Extragerea rezultatului
  96. int minim = -1;
  97. Punct loculIntalnirii;
  98. for (int i = 0; i < N; ++i) {
  99. for (int j = 0; j < M; ++j) {
  100. if (labirint[i][j] == 0 && vizitatTotal[i][j] == nr_pers && (drumuri[i][j] < minim || minim == -1)) {
  101. minim = drumuri[i][j];
  102. loculIntalnirii = make_pair(i, j);
  103. }
  104. }
  105. }
  106.  
  107. // Afisarea rezultatului
  108. printf("%d\n%d %d\n", minim, loculIntalnirii.first, loculIntalnirii.second);
  109.  
  110. return 0;
  111. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement