제출 #495648

#제출 시각아이디문제언어결과실행 시간메모리
495648600Mihnea바이러스 (JOI19_virus)C++17
100 / 100
724 ms25264 KiB
#include <bits/stdc++.h> using namespace std; int Transform(int x) { return x; } int codif(char ch) { if (ch == 'N') return Transform(0); if (ch == 'W') return Transform(1); if (ch == 'S') return Transform(2); if (ch == 'E') return Transform(3); assert(0); } mt19937 rng((long long) (new char)); const int M = 100000 + 7; const int N = 800 + 7; const int INF = (int) 1e9 + 7; int mod; int n; int m; string wind; int res[N][N], mx[1 << 4], cur[1 << 4], when[N][N]; bool valid[N][N]; int dr[] = {-1, 0, 1, 0}; int dc[] = {0, -1, 0, 1}; bool isOk(int r, int c) { if (min(r, c) < 1 || r > n || c > m) { return false; } if (res[r][c] == 0) { return false; } int whosValid = 0; for (int k = 0; k < 4; k++) { int rn = r + dr[k], cn = c + dc[k]; if (valid[rn][cn]) { whosValid += (1 << k); } } return mx[whosValid] >= res[r][c]; } signed main() { ios::sync_with_stdio(0); cin.tie(0); cin >> mod >> n >> m >> wind; for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { cin >> res[i][j]; } } wind += wind; for (auto &ch : wind) { int current = codif(ch); for (int mask = 0; mask < (1 << 4); mask++) { if (mask & (1 << current)) { cur[mask]++; mx[mask] = max(mx[mask], cur[mask]); } else { cur[mask] = 0; } } } for (int mask = 0; mask < (1 << 4); mask++) { if (mx[mask] >= mod) { mx[mask] = INF; } } vector<pair<int, int>> ord; for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { if (res[i][j]) { ord.push_back({i, j}); } } } shuffle(ord.begin(), ord.end(), rng); int y = 0; for (auto &it : ord) { when[it.first][it.second] = ++y; } int Minimum = (int) 1e9, cnt = 0; for (auto &it : ord) { int rinit = it.first, cinit = it.second; bool Evalid = true; queue<pair<int, int>> q; vector<pair<int, int>> all; q.push({rinit, cinit}); all.push_back({rinit, cinit}); valid[rinit][cinit] = true; while (!q.empty() && Evalid) { int r = q.front().first, c = q.front().second; q.pop(); for (int k = 0; k < 4; k++) { int rn = r + dr[k], cn = c + dc[k]; if (isOk(rn, cn) && !valid[rn][cn]) { q.push({rn, cn}); all.push_back({rn, cn}); valid[rn][cn] = true; if (when[rn][cn] < when[rinit][cinit]) { Evalid = false; break; } } } } for (auto &it : all) { valid[it.first][it.second] = 0; } if (!Evalid) { continue; } int current = (int) all.size(); if (current < Minimum) { Minimum = current; cnt = 0; } cnt += (Minimum == current); } cout << Minimum << " " << cnt * Minimum << "\n"; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...