p985.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. #include <iostream>
  2. #include <list>
  3. #include <string>
  4. #include <queue>
  5. #include <utility>
  6. #include <sstream>
  7. using namespace std;
  8. // Serves to keep track of any map, each bit is mapped to something
  9. uint8_t the_matrix[500][500];
  10. /*
  11. V3 V2 V1 V0 E3 E2 E1 E0
  12. Vx: Visited in this phase, V0 is the first phase
  13. Ex: Edge in this direction, E0 is to the north during phase 0, E1 to the west during phase 0 etc
  14. E0 is to the east during phase 1, E1 to the north during phase 1 etc
  15. */
  16. struct Agent
  17. {
  18. int x;
  19. int y;
  20. int steps;
  21. };
  22. enum Direction
  23. {
  24. NORTH,
  25. WEST,
  26. SOUTH,
  27. EAST,
  28. };
  29. bool check_dir(Agent smith, Direction dir)
  30. {
  31. return the_matrix[smith.x][smith.y] & (0x01 << ((dir+smith.steps)%4));
  32. }
  33. int main()
  34. {
  35. int width, height, steps;
  36. string str_in;
  37. ostringstream debug_stream;
  38. queue<Agent> search_queue;
  39. while(cin >> height >> width)
  40. {
  41. steps = 0;
  42. cin.ignore(1000, '\n');
  43. debug_stream << "Read width and height [" << width << "][" << height << "]\n";
  44. for(int y = 0; y < height; y++)
  45. {
  46. for(int x = 0; x < width; x++)
  47. {
  48. if(x == (width-1) && y == (height-1))
  49. {
  50. the_matrix[x][y] = 0;
  51. continue;
  52. }
  53. getline(cin, str_in);
  54. debug_stream << "Read line: " << str_in << endl;
  55. the_matrix[x][y] = (str_in.find('N') != string::npos) ? (1<<NORTH) : 0;
  56. the_matrix[x][y] |= (str_in.find('E') != string::npos) ? (1<<EAST) : 0;
  57. the_matrix[x][y] |= (str_in.find('S') != string::npos) ? (1<<SOUTH) : 0;
  58. the_matrix[x][y] |= (str_in.find('W') != string::npos) ? (1<<WEST) : 0;
  59. }
  60. }
  61. debug_stream << "populated the graph" << endl;
  62. for(int x = 0; x < width; x++)
  63. {
  64. for(int y = 0; y < height; y++)
  65. {
  66. debug_stream << x << ", " << y << ": 0x" << std::hex << (int)the_matrix[x][y] << endl;
  67. int phase = 4;
  68. if(check_dir(Agent{x,y,phase}, NORTH))
  69. {
  70. debug_stream << "Arrow to NORTH" << endl;
  71. }
  72. if(check_dir(Agent{x,y,phase}, EAST))
  73. {
  74. debug_stream << "Arrow to EAST" << endl;
  75. }
  76. if(check_dir(Agent{x,y,phase}, SOUTH))
  77. {
  78. debug_stream << "Arrow to SOUTH" << endl;
  79. }
  80. if(check_dir(Agent{x,y,phase}, WEST))
  81. {
  82. debug_stream << "Arrow to WEST" << endl;
  83. }
  84. }
  85. }
  86. // Clear queue
  87. while(!search_queue.empty())
  88. search_queue.pop();
  89. // Start in upper right corner
  90. search_queue.push(Agent{0,0,0});
  91. // Bredden först
  92. while(!search_queue.empty())
  93. {
  94. Agent smith = search_queue.front();
  95. search_queue.pop();
  96. debug_stream << "Searching [" << smith.x << "][" << smith.y << "] during phase " << smith.steps%4 << " (step " << smith.steps << ")\n";
  97. if(smith.x == width-1 && smith.y == height-1)
  98. {
  99. debug_stream << "Found exit!" << endl;
  100. steps = smith.steps;
  101. break;
  102. }
  103. if(the_matrix[smith.x][smith.y] & (0x10 << ((smith.steps)%4)))
  104. {
  105. // Already visited
  106. debug_stream << "Already visited" << endl;
  107. continue;
  108. }
  109. else
  110. {
  111. the_matrix[smith.x][smith.y] |= (0x10 << ((smith.steps)%4));
  112. }
  113. if(smith.y != 0 && check_dir(smith, NORTH))
  114. {
  115. debug_stream << "Possible to go NORTH" << endl;
  116. search_queue.push(Agent{smith.x,smith.y-1,smith.steps+1});
  117. }
  118. if(smith.x != width-1 && check_dir(smith, EAST))
  119. {
  120. debug_stream << "Possible to go EAST" << endl;
  121. search_queue.push(Agent{smith.x+1,smith.y,smith.steps+1});
  122. }
  123. if(smith.y != height-1 && check_dir(smith, SOUTH))
  124. {
  125. debug_stream << "Possible to go SOUTH" << endl;
  126. search_queue.push(Agent{smith.x,smith.y+1,smith.steps+1});
  127. }
  128. if(smith.x != 0 && check_dir(smith, WEST))
  129. {
  130. debug_stream << "Possible to go WEST" << endl;
  131. search_queue.push(Agent{smith.x-1,smith.y,smith.steps+1});
  132. }
  133. }
  134. if(steps)
  135. cout << steps << endl;
  136. else
  137. cout << "no path to exit" << endl;
  138. }
  139. return 0;
  140. }