Submission #1333648

#TimeUsernameProblemLanguageResultExecution timeMemory
1333648SmuggingSpunMaze (JOI23_ho_t3)C++20
100 / 100
545 ms267032 KiB
#include<bits/stdc++.h>
#define taskname "C"
using namespace std;
template<class T>bool minimize(T& a, T b){
  if(a > b){
    a = b;
    return true;
  }
  return false;
}
const int dirx[8] = {-1, 0, 1, 0, -1, -1, 1, 1}, diry[8] = {0, 1, 0, -1, -1, 1, 1, -1};
const int INF = 1e9;
int k, n, m, sx, sy, tx, ty;
vector<vector<char>>a;
namespace sub1{
  void solve(){
    vector<vector<int>>f(n + 1, vector<int>(m + 1, -1));
    f[sx][sy] = 0;
    deque<pair<int, int>>dq;
    dq.push_back(make_pair(sx, sy));
    while(!dq.empty()){
      tie(sx, sy) = dq.front();
      dq.pop_front();
      for(int i = 0; i < 4; i++){
        int tx = sx + dirx[i], ty = sy + diry[i];
        if(min(tx, ty) > 0 && tx <= n && ty <= m && f[tx][ty] == -1){
          if(a[tx][ty] == '#'){
            f[tx][ty] = f[sx][sy] + 1;
            dq.push_back(make_pair(tx, ty));
          }
          else{
            f[tx][ty] = f[sx][sy];
            dq.push_front(make_pair(tx, ty));
          }
        }
      }
    }
    cout << f[tx][ty];
  }
}
namespace sub2{
  struct Data{
    int x, y, w;
    Data(){}
    Data(int _x, int _y, int _w) : x(_x), y(_y), w(_w) {}
    friend bool operator <(const Data a, const Data b){
      return a.w > b.w;
    }
  };
  void solve(){
    vector<vector<int>>f(n + 1, vector<int>(m + 1, INF)), dp(n + 1, vector<int>(m + 1, INF));
    for(int i = dp[0][0] = 0; i <= n; i++){
      for(int j = int(i == 0); j <= m; j++){
        dp[i][j] = min(dp[max(0, i - k)][max(0, j - k + 1)], dp[max(0, i - k + 1)][max(0, j - k)]) + 1;
      }
    }
    priority_queue<Data>pq;
    pq.push(Data(sx, sy, f[sx][sy] = 0));
    int sw;
    while(!pq.empty()){
      Data cur = pq.top();
      pq.pop();
      if((sw = cur.w) == f[sx = cur.x][sy = cur.y]){
        for(int i = 0; i < 4; i++){
          int tx = sx + dirx[i], ty = sy + diry[i];
          if(min(tx, ty) > 0 && tx <= n && ty <= m && a[tx][ty] == '.' && minimize(f[tx][ty], sw)){
            pq.push(Data(tx, ty, sw));
          }
        }
        for(int tx = 1; tx <= n; tx++){
          for(int ty = 1; ty <= m; ty++){
            if(minimize(f[tx][ty], sw + dp[abs(tx - sx)][abs(ty - sy)])){
              pq.push(Data(tx, ty, f[tx][ty]));
            }
          }
        }
      }
    }
    cout << f[tx][ty];
  }
}
namespace sub45{
  void solve(){
    vector<set<int>>cand(n + 1);
    for(int i = 1; i <= n; i++){
      for(int j = 1; j <= m; j++){
        if(a[i][j] == '#'){
          cand[i].insert(j);
        }
      }
    }
    vector<pair<int, int>>p, np;
    function<void(int, int)>dfs;
    dfs = [&] (int x, int y){
      if(x < 1 || x > n || y < 1 || y > m || a[x][y] == '#'){
        return;
      }
      np.push_back(make_pair(x, y));
      a[x][y] = '#';
      for(int i = 0; i < 4; i++){
        dfs(x + dirx[i], y + diry[i]);
      }
    };
    dfs(sx, sy);
    swap(p, np);
    for(int iter = 0; true; iter++){
      if(a[tx][ty] == '#'){
        cout << iter;
        break;
      }
      np.clear();
      for(auto& [x, y] : p){
        for(int i = max(1, x - k); i <= min(n, x + k); i++){
          int left_bound = y - k + int(abs(i - x) == k), right_bound = y + k - int(abs(i - x) == k);
          for(auto it = cand[i].lower_bound(left_bound); it != cand[i].end() && *it <= right_bound; it++){
            a[i][*it] = '.';
            dfs(i, *it);
          }
          cand[i].erase(cand[i].lower_bound(left_bound), cand[i].upper_bound(right_bound));
        }
      }
      swap(p, np);
    }
  }
}
namespace sub3678{
  struct Data{
    int x, y, w, r;
    Data(){}
    Data(int _x, int _y, int _w, int _r) : x(_x), y(_y), w(_w), r(_r) {}
  };
  void solve(){
    vector<vector<bool>>vis(n + 1, vector<bool>(m + 1, false));
    deque<Data>dq;
    dq.push_back(Data(sx, sy, 0, 0));
    while(!dq.empty()){
      auto [sx, sy, sw, sr] = dq.front();
      dq.pop_front();
      if(sx == tx && sy == ty){
        return void(cout << sw);
      }
      if(!vis[sx][sy]){
        vis[sx][sy] = true;
        if(sr-- > 0){
          for(int i = 0; i < 8; i++){
            int tx = sx + dirx[i], ty = sy + diry[i];
            if(min(tx, ty) > 0 && tx <= n && ty <= m){
              dq.push_back(Data(tx, ty, sw, sr));
            }
          }
        }
        else{
          for(int i = 0; i < 4; i++){
            int tx = sx + dirx[i], ty = sy + diry[i];
            if(min(tx, ty) > 0 && tx <= n && ty <= m){
              if(a[tx][ty] == '.'){
                dq.push_front(Data(tx, ty, sw, 0));
              }
              else{
                dq.push_back(Data(tx, ty, sw + 1, k - 1));
              }
            }
          }
        }
      }
    }
  }
}
int main(){
	ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	if(fopen(taskname".inp", "r")){
		freopen(taskname".inp", "r", stdin);
	}
  cin >> n >> m >> k >> sx >> sy >> tx >> ty;
  a.assign(n + 1, vector<char>(m + 1));
  for(int i = 1; i <= n; i++){
    for(int j = 1; j <= m; j++){
      cin >> a[i][j];
    }
  }
  if(k == 1){
    sub1::solve();
  }
  else if(n * m <= 1000){
    sub2::solve();
  }
  else if(n * m <= 150000){
    sub45::solve();
  }
  else{
    sub3678::solve();
  }
}

Compilation message (stderr)

Main.cpp: In function 'int main()':
Main.cpp:172:24: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  172 |                 freopen(taskname".inp", "r", stdin);
      |                 ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...