sg1192k

Advent of Code Day 16 Part 2

Dec 16th, 2024
187
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.54 KB | None | 0 0
  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. bool marked[150][150];
  4. class Loc{
  5.   public:
  6.     int x,y,dir; //0-North, 1- East, 2-South, 3-West
  7.     bool operator<(const Loc& other) const {
  8.         if (x < other.x) {
  9.             return true;
  10.         } else if (x > other.x) {
  11.             return false;
  12.         }
  13.         if (y < other.y) {
  14.             return true;
  15.         } else if (y > other.y) {
  16.             return false;
  17.         }
  18.         return dir < other.dir;
  19.     }
  20. };
  21. bool inside(int i,int j,int n,vector<vector<char>>&v){
  22.     return (i>=0&&i<n&&j>=0&&j<n&&v[i][j]!='#');
  23. }
  24. void dijkstra(int n,map<Loc,vector<pair<Loc,int>>>&adj,Loc s, map<Loc,int>& d, map<Loc,vector<Loc>>& p) {
  25.     d[s] = 0;
  26.     p[s] = {{-1,-1,-1}};
  27.     using pil = pair<int, Loc>;
  28.     priority_queue<pil, vector<pil>, greater<pil>> q;
  29.     q.push({0, s});
  30.     while (!q.empty()) {
  31.         Loc v = q.top().second;
  32.         int d_v = q.top().first;
  33.         q.pop();
  34.         if (d_v != d[v])
  35.             continue;
  36.         for (auto edge : adj[v]) {
  37.             Loc to = edge.first;
  38.             int len = edge.second;
  39.  
  40.             if(d.find(to)==d.end()) d[to]=1e9+10;
  41.             if(p.find(to)==p.end()) p[to]={{-1,-1,-1}};
  42.  
  43.             if (d[v] + len < d[to]) {
  44.                 p[to].clear();
  45.                 d[to] = d[v] + len;
  46.                 p[to]={v};
  47.                 q.push({d[to], to});
  48.             }
  49.             else if(d[v]+len==d[to]){
  50.                 p[to].push_back(v);
  51.             }
  52.         }
  53.     }
  54. }
  55. void mark(Loc src,map<Loc,vector<Loc>>&p){
  56.     if(src.x==-1&&src.y==-1) return;
  57.     marked[src.x][src.y]=true;
  58.     for(auto par:p[src]){
  59.         mark(par,p);
  60.     }
  61. }
  62. int main(){
  63.     freopen("input.txt","r",stdin);
  64.     freopen("output.txt","w",stdout);
  65.     int n=141,ans=0;
  66.     Loc start,target;
  67.     vector<vector<char>>v(n,vector<char>(n));
  68.     for(int i=0;i<n;i++){
  69.         for(int j=0;j<n;j++){
  70.             cin>>v[i][j];
  71.             if(v[i][j]=='S'){
  72.                 start.x=i;
  73.                 start.y=j;
  74.                 start.dir=1;
  75.             }
  76.             else if(v[i][j]=='E'){
  77.                 target.x=i;
  78.                 target.y=j;
  79.                 target.dir=-1;
  80.             }
  81.         }
  82.     }
  83.     map<Loc,vector<pair<Loc,int>>>adj;
  84.     for(int i=0;i<n;i++){
  85.         for(int j=0;j<n;j++){
  86.             for(int k=0;k<4;k++){
  87.                 if(!inside(i,j,n,v)) continue;
  88.                 adj[{i,j,k}].push_back({{i,j,(k+1)%4},1000});
  89.                 adj[{i,j,k}].push_back({{i,j,(k+3)%4},1000});
  90.                 if(k==0&&inside(i-1,j,n,v)){
  91.                     adj[{i,j,k}].push_back({{i-1,j,k},1});
  92.                 }
  93.                 if(k==1&&inside(i,j+1,n,v)){
  94.                     adj[{i,j,k}].push_back({{i,j+1,k},1});
  95.                 }
  96.                 if(k==2&&inside(i+1,j,n,v)){
  97.                     adj[{i,j,k}].push_back({{i+1,j,k},1});
  98.                 }
  99.                 if(k==3&&inside(i,j-1,n,v)){
  100.                     adj[{i,j,k}].push_back({{i,j-1,k},1});
  101.                 }
  102.             }
  103.         }
  104.     }
  105.  
  106.     map<Loc,int>d;
  107.     map<Loc,vector<Loc>>p;
  108.     dijkstra(n,adj,start,d,p);
  109.  
  110.     memset(marked,false,sizeof(marked));
  111.     int target_cost=min({d[{target.x,target.y,0}],d[{target.x,target.y,1}],d[{target.x,target.y,2}],d[{target.x,target.y,3}]});
  112.     for(int k=0;k<4;k++){
  113.         Loc tmp={target.x,target.y,k};
  114.         if(d[tmp]==target_cost) mark(tmp,p);
  115.     }
  116.     for(int i=0;i<n;i++){
  117.         for(int j=0;j<n;j++){
  118.             if(marked[i][j]) ans++;
  119.         }
  120.     }
  121.     cout<<ans;
  122.     return 0;
  123. }
Advertisement
Add Comment
Please, Sign In to add comment