diff --git a/day 20/day_20_max_n.cpp b/day 20/day_20_max_n.cpp new file mode 100644 index 0000000000000000000000000000000000000000..741af9393d4433e65ea24f1b935725c5abe11775 --- /dev/null +++ b/day 20/day_20_max_n.cpp @@ -0,0 +1,131 @@ +#include <bits/stdc++.h> + +#ifdef LOCAL +#include "./cpp-dump/cpp-dump.hpp" +#define pr(x) cpp_dump(x) +#endif + +using namespace std; + +#define Mod(x,y) (((x)%(y)+(y))%(y)) +#define rep(i, a, b) for(ll (i) = (a); (i) < (b); ++(i)) +#define all(x) begin(x), end(x) +#define pb push_back +#define gcd __gcd +#define sz(x) (ll)(x.size()) + +typedef long long ll; +typedef unsigned long long ull; +typedef pair<ll, ll> pii; +typedef vector<ll> vi; +typedef vector<pii> vii; + +const bool debug = false; + +vector<string> mat; +int n, m; +int i4[4] = {-1, 0, 0, 1}; +int j4[4] = { 0,-1, 1, 0}; + +typedef pii TT; // often ll or string or pii + +vector<pair<ll, TT>> get_edges(TT u, char pass_through) { // here it is possible to implement an infinite graph + + vector<pair<ll, TT>> edges; // this is example for 2d graph without explicit gr + rep(x, 0, 4) { // or rep(di, -1, 2) rep(dj, -1, 2) if (di != 0 || dj != 0) + int i = u.first + i4[x], j = u.second + j4[x]; + if (pass_through == '.' && min(i, j) >= 0 && i < n && j < m && mat[i][j] == '.') { + edges.pb(pair<ll, pii>(1, pii(i, j))); + } + if (pass_through == '#' && min(i, j) >= 0 && i < n && j < m) { + edges.pb(pair<ll, pii>(1, pii(i, j))); + } + } + + return edges; +} + +map<TT, ll> dijkstra(TT src, ll mx_time, char pass_through) { // needs a defined get_edges, and if you want to return dist/prev just ... + map<TT, ll> dist; + map<TT, TT> prev; + set<TT> vis; + priority_queue<pair<ll, TT>, vector<pair<ll, TT>>, greater<pair<ll, TT>>> pq; + dist[src] = 0; + pq.push(pair<ll, TT>(0, src)); + + while(pq.size()) { + pair<ll, TT> p = pq.top(); pq.pop(); + ll du = p.first; + TT u = p.second; + if (dist[u] < du) continue; + + for (auto [d, v] : get_edges(u, pass_through)) { + if (dist[u] + d > mx_time) // + break; + + if (dist.count(v) == 0 || dist[v] > dist[u] + d) { + dist[v] = dist[u] + d; + prev[v] = u; + pq.push(pair<ll, TT>(dist[v], v)); + } + } + } + + return dist; // ... and change this to corresponding output +} + +void solve() { + string s; + while(cin >> s) mat.pb(s); + n = sz(mat); + m = sz(mat[0]); + + pii src, targ; + rep(i, 0, n) rep(j, 0, m) { + if (mat[i][j] == 'S') { + src = pii(i, j); + mat[i][j] = '.'; + } + if (mat[i][j] == 'E') { + targ = pii(i, j); + mat[i][j] = '.'; + } + } + + ll mx_time = 20; + + map<TT, ll> normal = dijkstra(src, LLONG_MAX, '.'); + map<ll, set<pair<pii, pii>>> save; + + rep(i, 1, n-1) rep(j, 1, m-1) { + + if (mat[i][j] == '.') { + map<TT, ll> cheat = dijkstra(pii(i, j), mx_time, '#'); + for (auto p : cheat) { + pii q = p.first; + int x = q.first, y = q.second; + if (mat[x][y] == '.' && normal[pii(i, j)] + p.second < normal[q]) { + ll to_save = normal[q] - (normal[pii(i, j)] + p.second); + save[to_save].insert(make_pair(pii(i, j), pii(x, y))); + + } + } + } + } + + ll ans = 0; + for (auto p : save) if (p.first >= 100) ans += sz(p.second); + pr(ans); +} + + +int main() { + ios::sync_with_stdio(0);cin.tie(0); + cout << setprecision(15) << fixed; + +#ifdef LOCAL + freopen("input.txt", "r", stdin); +#endif + + solve(); +}