Skip to content

Instantly share code, notes, and snippets.

@MinecraftFuns
Created November 17, 2020 10:39
Show Gist options
  • Save MinecraftFuns/dd7ad9f8ed6a1d37eb44061a46d570d7 to your computer and use it in GitHub Desktop.
Save MinecraftFuns/dd7ad9f8ed6a1d37eb44061a46d570d7 to your computer and use it in GitHub Desktop.
#include <bits/stdc++.h>
#define alive std::cout << "$LINE @" << __LINE__ << " ALIVE" << std::endl
#define watch(var) std::cout << "$ LINE @" << __LINE__ << " FUN @" << __FUNCTION__ \
<< " VAR @" << (#var) << ": " << (var) << std::endl
using namespace std;
typedef int i32;
typedef unsigned int u32;
typedef long long i64;
typedef unsigned long long u64;
typedef double f64;
typedef long double f128;
typedef pair<int, int> pii;
template <typename Tp>
inline void read(Tp &x)
{
x = 0;
bool neg = false;
char c = getchar();
for (; !isdigit(c); c = getchar())
{
if (c == '-')
{
neg = true;
}
}
for (; isdigit(c); c = getchar())
{
x = x * 10 + c - '0';
}
if (neg)
{
x = -x;
}
}
const int N = 50 + 5;
const int M = 10000 + 5;
int n, m;
char mp[N][N], S[M];
pii L[N][N], R[N][N], U[N][N], D[N][N];
struct Status
{
int x, y, dep, cost;
inline Status(const int &x, const int &y, const int &dep, const int &cost)
{
this->x = x;
this->y = y;
this->dep = dep;
this->cost = cost;
}
};
int vis[N][N];
int main()
{
read(n), read(m);
for (int i = 1; i <= n; ++i)
{
scanf("%s", mp[i] + 1);
}
scanf("%s", S + 1);
int lenS = strlen(S + 1);
S[++lenS] = '*';
for (int i = 1; i <= n; ++i)
{
for (int j = 1; j <= m; ++j)
{
if (mp[i][j] == mp[i][j - 1])
{
L[i][j] = L[i][j - 1];
}
else
{
L[i][j] = (pii){i, j - 1};
}
if (mp[i][j] == mp[i - 1][j])
{
U[i][j] = U[i - 1][j];
}
else
{
U[i][j] = (pii){i - 1, j};
}
}
}
for (int i = n; i >= 1; --i)
{
for (int j = m; j >= 1; --j)
{
if (mp[i][j] == mp[i][j + 1])
{
R[i][j] = R[i][j + 1];
}
else
{
R[i][j] = (pii){i, j + 1};
}
if (mp[i][j] == mp[i + 1][j])
{
D[i][j] = D[i + 1][j];
}
else
{
D[i][j] = (pii){i + 1, j};
}
}
}
memset(vis, -1, sizeof(vis));
queue<Status> q;
q.emplace(1, 1, 0, 0);
auto transfer = [&](const Status &cur, const pii(&leap)[55][55]) {
const int &nx = leap[cur.x][cur.y].first,
&ny = leap[cur.x][cur.y].second;
if ((nx < 1 || nx > n) ||
(ny < 1 || ny > m))
{
return;
}
if (vis[nx][ny] < cur.dep)
{
vis[nx][ny] = cur.dep;
q.emplace(nx, ny, cur.dep, cur.cost + 1);
}
};
while (!q.empty())
{
Status cur = q.front();
q.pop();
if (cur.dep == lenS)
{
printf("%d\n", cur.cost);
return 0;
}
if (mp[cur.x][cur.y] == S[cur.dep + 1] && vis[cur.x][cur.y] < cur.dep + 1)
{
vis[cur.x][cur.y] = cur.dep + 1;
q.emplace(cur.x, cur.y, cur.dep + 1, cur.cost + 1);
}
transfer(cur, L);
transfer(cur, R);
transfer(cur, U);
transfer(cur, D);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment