This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
#define task "SNAKE"
using namespace std;
const int N = 1e3 + 5;
int n, m, A[N][N];
struct Data
{
int x, y;
} S, C, D;
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
struct Data2
{
int x, y, w;
} P;
struct cmp
{
bool operator() (Data2 A, Data2 B)
{
return A.w > B.w;
}
};
int Up[N][N], Down[N][N], Left[N][N], Right[N][N];
void init()
{
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= m; j++)
{
Left[i][j] = Left[i][j-1] + 1;
if(A[i][j] == 0) Left[i][j] = 0;
}
for(int j = m; j >= 1; j--)
{
Right[i][j] = Right[i][j + 1] + 1;
if(A[i][j] == 0) Right[i][j] = 0;
}
}
for(int j = 1; j <= m; j++)
{
for(int i = 1; i <= n; i++)
{
Up[i][j] = Up[i-1][j] + 1;
if(A[i][j] == 0) Up[i][j] = 0;
}
for(int i = n; i >= 1; i--)
{
Down[i][j] = Down[i + 1][j] + 1;
if(A[i][j] == 0) Down[i][j] = 0;
}
}
}
priority_queue < Data2, vector < Data2 > , cmp > pq;
namespace sub5
{
queue < Data > Q;
int Visited[N][N], dist[N][N], wall[N][N];
void Build()
{
for(int i = 0; i <= n + 1; i++)
for(int j = 0; j <= m + 1; j++)
if(A[i][j] == 0) Q.push({i, j}), Visited[i][j] = 1;
while(!Q.empty())
{
Data D = Q.front(); Q.pop();
for(int i = 0; i < 4; i++)
{
int x = D.x + dx[i];
int y = D.y + dy[i];
if(A[x][y] && !Visited[x][y])
{
Q.push({x, y});
wall[x][y] = wall[D.x][D.y] + 1;
Visited[x][y] = 1;
}
}
}
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++) Visited[i][j] = 0, dist[i][j] = 1e9;
}
void Go(int x, int y, int cost)
{
if(dist[x][y] <= dist[P.x][P.y] + cost) return;
dist[x][y] = dist[P.x][P.y] + cost;
pq.push({x, y, dist[x][y]});
}
void solve()
{
Build();
pq.push({S.x, S.y, 0}); dist[S.x][S.y] = 0;
while(!pq.empty())
{
P = pq.top(); pq.pop();
for(int i = 0; i < 4; i++)
{
int x = P.x + dx[i];
int y = P.y + dy[i];
if(A[x][y]) Go(x, y, 1);
}
int x, y;
x = P.x - (Up[P.x][P.y] - 1); y = P.y;
Go(x, y, wall[P.x][P.y]);
x = P.x + (Down[P.x][P.y] - 1); y = P.y;
Go(x, y, wall[P.x][P.y]);
x = P.x; y = P.y - (Left[P.x][P.y] - 1);
Go(x, y, wall[P.x][P.y]);
x = P.x; y = P.y + (Right[P.x][P.y] - 1);
Go(x, y, wall[P.x][P.y]);
}
cout << dist[C.x][C.y];
}
}
int main()
{
if(fopen(task ".inp","r"))
{
freopen(task ".inp","r",stdin);
freopen(task ".out","w",stdout);
}
ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
cin >> n >> m;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
{
char ch;
cin >> ch;
if(ch == 'S') S = {i, j};
if(ch == 'C') C = {i, j};
if(ch != '#') A[i][j] = 1;
}
init();
sub5::solve();
}
Compilation message (stderr)
portals.cpp: In function 'int main()':
portals.cpp:119:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
119 | freopen(task ".inp","r",stdin);
| ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~
portals.cpp:120:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
120 | freopen(task ".out","w",stdout);
| ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |