#include <cstdint> #include <cstring> #include <inttypes.h> #include <limits> #include <map> #include <set> #include <stack> #include <utility> #include <queue> #define fprintf(...) namespace { using u8 = std::uint8_t; using u32 = std::uint32_t; using u64 = std::uint64_t; constexpr int MOVE[4][2] = { {1,0}, {0,1}, {-1,0}, {0,-1}}; u8 board[2000][2000]; int Y_FINAL; int X_FINAL; char line[2005]; struct Point { int x, y; Point(int _x, int _y) noexcept : x(_x), y(_y) {} }; struct Item { Point point; u32 distance; Item(int x, int y, u32 d) noexcept : point(x,y), distance(d) {} }; u32 solve() { std::queue<Item> points; points.emplace(0, 0, 0); board[0][0] = 1; while (not points.empty()) { const auto& item = points.front(); const auto& point = item.point; fprintf(stderr, "process [%d : %d]\n", point.x, point.y); if ((X_FINAL == point.x) and (Y_FINAL == point.y)) { return item.distance; } points.pop(); for (int i = 0; i < 4; i++) { int newX = point.x + MOVE[i][0]; int newY = point.y + MOVE[i][1]; //fprintf(stderr, " checking new point [%d : %d]\n", newX, newY); // if adjacent cell is valid, has path and // not visited yet, enqueue it. if (((newX >= 0) and (newX <= X_FINAL) and (newY >= 0) and (newY <= Y_FINAL)) and (0 == board[newY][newX])) { board[newY][newX] = 1; points.emplace(newX, newY, item.distance+1); fprintf(stderr, " points.emplace(%u, %u, %u)\n", newX, newY, item.distance+1); } } } return 0; } } //namespace int main() { u32 n, m, k; scanf("%u %u %u", &n, &m, &k); Y_FINAL = n-1; X_FINAL = m-1; for(u32 i=0; i<n; ++i) { (void)scanf("%s", line); for(u32 j=0; j<m; ++j) { board[i][j] = (line[j] != '.'); } } u32 length = solve(); const u64 ups = (Y_FINAL+X_FINAL) + (length-Y_FINAL-X_FINAL)/2; const u64 downs = length - ups; fprintf(stderr, "\n\n length = %u ups=%"PRIu64" downs=%"PRIu64"\n", length, ups, downs); std::pair<u64,u32> result{std::numeric_limits<u64>::max(), 0}; for(u32 i=0; i<k; ++i) { (void)scanf("%u %u", &n, &m); u64 time = n*ups + m*downs; if(time < result.first) { result.first = time; result.second = 1; } else if(time == result.first) { result.second++; } } printf("%" PRIu64" %u\n", result.first, result.second); return 0; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | #include <cstdint> #include <cstring> #include <inttypes.h> #include <limits> #include <map> #include <set> #include <stack> #include <utility> #include <queue> #define fprintf(...) namespace { using u8 = std::uint8_t; using u32 = std::uint32_t; using u64 = std::uint64_t; constexpr int MOVE[4][2] = { {1,0}, {0,1}, {-1,0}, {0,-1}}; u8 board[2000][2000]; int Y_FINAL; int X_FINAL; char line[2005]; struct Point { int x, y; Point(int _x, int _y) noexcept : x(_x), y(_y) {} }; struct Item { Point point; u32 distance; Item(int x, int y, u32 d) noexcept : point(x,y), distance(d) {} }; u32 solve() { std::queue<Item> points; points.emplace(0, 0, 0); board[0][0] = 1; while (not points.empty()) { const auto& item = points.front(); const auto& point = item.point; fprintf(stderr, "process [%d : %d]\n", point.x, point.y); if ((X_FINAL == point.x) and (Y_FINAL == point.y)) { return item.distance; } points.pop(); for (int i = 0; i < 4; i++) { int newX = point.x + MOVE[i][0]; int newY = point.y + MOVE[i][1]; //fprintf(stderr, " checking new point [%d : %d]\n", newX, newY); // if adjacent cell is valid, has path and // not visited yet, enqueue it. if (((newX >= 0) and (newX <= X_FINAL) and (newY >= 0) and (newY <= Y_FINAL)) and (0 == board[newY][newX])) { board[newY][newX] = 1; points.emplace(newX, newY, item.distance+1); fprintf(stderr, " points.emplace(%u, %u, %u)\n", newX, newY, item.distance+1); } } } return 0; } } //namespace int main() { u32 n, m, k; scanf("%u %u %u", &n, &m, &k); Y_FINAL = n-1; X_FINAL = m-1; for(u32 i=0; i<n; ++i) { (void)scanf("%s", line); for(u32 j=0; j<m; ++j) { board[i][j] = (line[j] != '.'); } } u32 length = solve(); const u64 ups = (Y_FINAL+X_FINAL) + (length-Y_FINAL-X_FINAL)/2; const u64 downs = length - ups; fprintf(stderr, "\n\n length = %u ups=%"PRIu64" downs=%"PRIu64"\n", length, ups, downs); std::pair<u64,u32> result{std::numeric_limits<u64>::max(), 0}; for(u32 i=0; i<k; ++i) { (void)scanf("%u %u", &n, &m); u64 time = n*ups + m*downs; if(time < result.first) { result.first = time; result.second = 1; } else if(time == result.first) { result.second++; } } printf("%" PRIu64" %u\n", result.first, result.second); return 0; } |