이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <bits/stdc++.h>
#define IO_OP std::ios::sync_with_stdio(0); std::cin.tie(0);
#define F first
#define S second
#define V vector
#define PB push_back
#define MP make_pair
#define EB emplace_back
#define ALL(v) (v).begin(), (v).end()
using namespace std;
typedef long long ll;
typedef pair<int, int> pi;
typedef V<int> vi;
string to_string(char c) { return string(1, c); }
string to_string(bool b) { return b?"true":"false"; }
string to_string(const char* s) { return string(s); }
string to_string(string s) { return s; }
string to_string(V<bool> v) {
string res;
for(int i=0;i<(int)v.size();i++) res+=char('0'+v[i]);
return res;
}
template<class T1, class T2> string to_string(pair<T1, T2> p) {return "(" + to_string(p.F) + ", " + to_string(p.S) + ")";}
template<size_t S> string to_string(bitset<S> b) {
string res;
for(int i=0;i<S;i++) res+=char('0'+b[i]);
return res;
}
template<class T> string to_string(T v) {
bool f=1;
string res;
for(auto x:v){
if(!f) res+=' ';
f=0; res+=to_string(x);
}
return res;
}
string _reset = "\u001b[0m", _yellow = "\u001b[33m", _bold = "\u001b[1m";
void DBG() { cerr << "]" << _reset << endl; }
template<class H, class...T> void DBG(H h, T ...t) {
cerr << to_string(h);
if(sizeof ...(t)) cerr << ", ";
DBG(t...);
}
#ifdef CHEISSMART
#define debug(...) cerr << _yellow << _bold << "Line(" << __LINE__ << ") -> [" << #__VA_ARGS__ << "]: [", DBG(__VA_ARGS__)
#else
#define debug(...)
#endif
const int INF = 1e9 + 7, N = 808;
string DIR = "NESW";
int di[] = {-1, 0, 1, 0}, dj[] = {0, 1, 0, -1};
int a[N][N];
int r, c, m;
bool can[N][N][1 << 4];
int get_len(vi& v) {
int mx = 0, cur = 0;
for(int i:v) {
if(i == 0) {
mx = max(mx, cur);
cur = 0;
} else {
cur++;
}
}
mx = max(mx, cur);
return mx;
}
pi p[N][N];
V<pi> rp[N][N];
bool dead[N][N];
pi who[N][N];
pi& P(pi u) { return p[u.F][u.S]; }
V<pi>& RP(pi u) { return rp[u.F][u.S]; }
pi& WHO(pi u) { return who[u.F][u.S]; }
bool& DEAD(pi u) {
u = WHO(P(u));
return dead[u.F][u.S];
}
void unite(pi u, pi v) {
u = P(u), v = P(v);
if(u == v) return;
debug(u.F, u.S, v.F, v.S);
pi new_rep = WHO(v);
if(RP(u).size() > RP(v).size()) swap(u, v);
for(pi e:RP(u)) {
RP(v).PB(e);
P(e) = v;
}
RP(u).clear();
WHO(v) = new_rep;
}
int vis[N][N], cnt = 0;
bool valid(int i, int j) {
return 0 <= i && i < r && 0 <= j && j < c;
}
pair<pi, int> BFS(pi s) {
assert(WHO(P(s)) == s);
cnt++;
int res = 0;
queue<pi> q;
pi x = {-1, -1};
auto add = [&] (int i, int j) {
assert(p[i][j] == P(s));
assert(vis[i][j] != cnt);
vis[i][j] = cnt;
res++;
q.push(MP(i, j));
};
auto check = [&] (int i, int j) {
int mask = 0;
for(int k = 0; k < 4; k++) {
int ii = i + di[k], jj = j + dj[k];
if(valid(ii, jj) && vis[ii][jj] == cnt) {
mask |= 1 << k;
}
}
return can[i][j][mask];
};
add(s.F, s.S);
while(q.size()) {
auto [i, j] = q.front(); q.pop();
for(int k = 0; k < 4; k++) {
int ii = i + di[k], jj = j + dj[k];
if(valid(ii, jj) && vis[ii][jj] != cnt) {
if(check(ii, jj)) {
if(s == MP(2, 3)) {
debug(ii, jj);
}
if(p[ii][jj] == P(s)) {
add(ii, jj);
} else {
x = {ii, jj};
}
}
}
}
}
return {x, res};
}
signed main()
{
IO_OP;
string ds;
cin >> m >> r >> c >> ds;
vi d;
for(char _:ds)
d.PB(int(find(ALL(DIR), _) - DIR.begin()));
for(int i = 0; i < r; i++)
for(int j = 0; j < c; j++)
cin >> a[i][j];
for(int mask = 0; mask < (1 << 4); mask++) {
vi td;
for(int i:d) td.PB(mask >> i & 1);
int len = INF;
if(find(ALL(td), 0) != td.end()) {
for(int i = 0; i < int(d.size()); i++)
td.PB(td[i]);
len = get_len(td);
}
for(int i = 0; i < r; i++) {
for(int j = 0; j < c; j++) if(a[i][j] && a[i][j] <= len) {
can[i][j][mask] = true;
}
}
}
for(int i = 0; i < r; i++) {
for(int j = 0; j < c; j++) {
who[i][j] = p[i][j] = {i, j};
rp[i][j].EB(i, j);
}
}
int ans = INF, cnt = 0;
for(int _ = 0; _ < 100; _++) {
V<pair<pi, pi>> todo;
for(int i = 0; i < r; i++) for(int j = 0; j < c; j++) if(a[i][j]) {
if(WHO(P(MP(i, j))) == MP(i, j) && !DEAD(MP(i, j))) {
pair<pi, int> x = BFS({i, j});
if(x.F.F == -1) { // no new
if(x.S < ans) ans = x.S, cnt = x.S;
else if(x.S == ans) cnt += x.S;
debug(i, j, x, RP(MP(i, j)));
DEAD(MP(i, j)) = true;
} else {
todo.EB(MP(i, j), x.F);
}
}
}
if(todo.empty()) break;
for(auto [u, v] : todo)
unite(u, v);
}
cout << ans << '\n' << cnt << '\n';
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |