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>
using namespace std;
#define amax(a, b) a = max(a, b)
#define cellid(r, c) (r*C+c)
#define extract(cell) (cell/C)][(cell%C)
constexpr int INF = 1e9+42;
int M, R, C;
vector<vector<int>> U;
string to_s(int cell) {
return to_string(cell/C)+","+to_string(cell%C);
}
struct patate {
int centre;
int num_cases = 1;
bool operator<(const patate& other) const {
return num_cases > other.num_cases;
}
};
struct Dir {
int v, h;
inline bool ok(int cell) {
int r = cell/C, c = cell%C;
if (0 <= r+v && r+v < R && 0 <= c+h && c+h < C && U[r+v][c+h]) {
return true;
} else {
return false;
}
}
inline int next(int cell) {
return cell+h+v*C;
}
};
const Dir DIRS[] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
int maxconsecutive[1<<4];
vector<int> uf;
vector<int> numchilds;
priority_queue<patate> pq;
int timer = 1;
vector<int> vu;
vector<int> bestcost;
vector<bool> potentiel_opt;
int ans = INF;
int ansq = 0;
int root(int u) {
return uf[u] == u ? u : uf[u] = root(uf[u]);
}
int main() {
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
cin >> M >> R >> C;
string dirs;
cin >> dirs;
dirs.append(dirs);
char _map[256];
_map['S'] = 0;
_map['W'] = 1;
_map['N'] = 2;
_map['E'] = 3;
uf.resize(R*C);
vu.resize(R*C);
numchilds.assign(R*C, 1);
bestcost.assign(R*C, INF);
potentiel_opt.resize(R*C);
iota(uf.begin(), uf.end(), 0);
for (int mask = 0; mask < 1<<4; mask++) {
int l = 0;
for (char c : dirs) {
if ((mask >> _map[(unsigned char)c]) & 1) l++;
else l = 0;
maxconsecutive[mask] = max(maxconsecutive[mask], l);
}
if (maxconsecutive[mask] >= M) maxconsecutive[mask] = INF;
}
U.assign(R, vector<int>(C));
for (int r = 0; r < R; r++) {
for (int c = 0; c < C; c++) {
cin >> U[r][c];
if (U[r][c]) {
pq.push({cellid(r, c), 1});
}
}
}
while (!pq.empty()) {
auto cur = pq.top(); pq.pop();
if (root(cur.centre) != cur.centre || numchilds[cur.centre] != cur.num_cases) continue;
timer++;
queue<int> q;
q.push(cur.centre);
vu[cur.centre] = timer;
bool stopbfs = false;
int num_explore = 0;
vector<int> explored;
while (!q.empty() && !stopbfs) {
auto u = q.front(); q.pop();
explored.push_back(u);
num_explore++;
for (auto dir : DIRS) {
int next = dir.next(u);
if (dir.ok(u)) {
int i = 2;
int mask = 0;
for (auto dir2 : DIRS) {
int k = dir2.next(next);
if (dir2.ok(next) && vu[k] == vu[cur.centre]) {
mask += 1<<i;
}
i++, i &= 3;
}
if (U[extract(next)] <= maxconsecutive[mask]) {
if (vu[next] != timer && root(next) == cur.centre) {
vu[next] = timer;
q.push(next);
} else if (root(next) != cur.centre) {
uf[cur.centre] = root(next);
numchilds[root(next)] += numchilds[cur.centre];
if (!potentiel_opt[root(next)]) pq.push({root(next), numchilds[root(next)]});
stopbfs = true;
break;
}
}
}
}
}
if (!stopbfs) {
if (num_explore == ans) {
ansq += num_explore;
} else if (num_explore < ans) {
ans = num_explore;
ansq = num_explore;
}
potentiel_opt[cur.centre] = true;
}
}
cout << ans << '\n' << ansq << '\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... |