day20b.cpp (2197B)
1 #include <algorithm> 2 #include <cstdint> 3 #include <iostream> 4 #include <map> 5 #include <queue> 6 #include <ranges> 7 #include <set> 8 #include <sstream> 9 #include <string> 10 #include <string_view> 11 #include <vector> 12 using namespace std; 13 14 class Map { 15 public: 16 int N, M, L; 17 int *cell; 18 19 Map(const vector<string>& lines) 20 : N{(int)lines.size()}, M{(int)lines[0].size()}, cell{new int[M*N]} 21 { 22 for (int i = 0; i < N; i++) { 23 for (int j = 0; j < N; j++) { 24 cell[M*i+j] = lines[i][j] == '#' ? -1 : 0; 25 if (lines[i][j] == 'S') { 26 is = i; 27 js = j; 28 } 29 if (lines[i][j] == 'E') { 30 ie = i; 31 je = j; 32 } 33 } 34 } 35 findpath(); 36 } 37 38 ~Map() { 39 delete[] cell; 40 } 41 42 int& operator()(int i, int j) { 43 if (i < 0 || i >= N || j < 0 || j >= M) 44 return out_of_bound; 45 return cell[M*i+j]; 46 } 47 48 const int& operator()(int i, int j) const { 49 if (i < 0 || i >= N || j < 0 || j >= M) 50 return out_of_bound; 51 return cell[M*i+j]; 52 } 53 54 int cheats(int x, int y, int k, int p) { 55 // Cheats <= p starting at x, y saving at least k picoseconds 56 57 int count = 0; 58 for (int i = 0; i < N; i++) 59 for (int j = 0; j < M; j++) 60 if ((*this)(i, j) != -1) 61 count += saved(i, j, x, y, p) >= k; 62 63 return count; 64 } 65 private: 66 int is, js, ie, je; 67 int out_of_bound = -1; 68 vector<pair<int, int>> directions {{0,1}, {0,-1}, {1,0}, {-1,0}}; 69 70 void findpath() { 71 int i, j, k; 72 for (i = is, j = js, k = 1; i != ie || j != je; step(i, j, k)) 73 (*this)(i, j) = k; 74 (*this)(ie, je) = k; 75 L = k-1; 76 } 77 78 void step(int& i, int& j, int& k) { 79 k++; 80 for (auto p : directions) { 81 if ((*this)(i+p.first, j+p.second) == 0) { 82 i = i+p.first; 83 j = j+p.second; 84 return; 85 } 86 } 87 cout << "Error! at " << i << ", " << j << endl; 88 } 89 90 int saved(int i, int j, int x, int y, int p) { 91 if (int d = abs(i-x) + abs(j-y); d > p) 92 return 0; 93 else 94 return abs((*this)(i, j) - (*this)(x, y)) - d; 95 } 96 }; 97 98 int main() { 99 string line; 100 vector<string> lines; 101 while (getline(cin, line)) 102 lines.push_back(line); 103 Map m(lines); 104 105 int count = 0; 106 for (int i = 0; i < m.N; i++) 107 for (int j = 0; j < m.M; j++) 108 if (m(i, j) != -1) 109 count += m.cheats(i, j, 100, 20); 110 111 cout << count / 2 << endl; 112 113 return 0; 114 }