제출 #794524

#제출 시각아이디문제언어결과실행 시간메모리
794524peijar바이러스 (JOI19_virus)C++17
100 / 100
672 ms32160 KiB
#include <bits/stdc++.h> #define int long long using namespace std; #define all(v) (v).begin(), (v).end() #define rall(v) (v).rbegin(), (v).rend() #define rep(i, a, b) for(int i = (a); i < (b); i++) #define sz(v) ((int)((v).size())) template<typename T> void chmax(T &x, const T &v) { if (x < v) x = v; } template<typename T> void chmin(T &x, const T &v) { if (x > v) x = v; } using pii = pair<int, int>; using vi = vector<int>; string to_string(string s) { return s; } template <typename T> string to_string(T v) { bool first = true; string res = "["; for (const auto &x : v) { if (!first) res += ", "; first = false; res += to_string(x); } res += "]"; return res; } template <typename A, typename B> string to_string(pair<A, B> p) { return "(" + to_string(p.first) + ", " + to_string(p.second) + ")"; } void dbg_out() { cout << endl; } template <typename Head, typename... Tail> void dbg_out(Head H, Tail... T) { cout << ' ' << to_string(H); dbg_out(T...); } #ifdef DEBUG #define dbg(...) cout << "(" << #__VA_ARGS__ << "):", dbg_out(__VA_ARGS__) #else #define dbg(...) #endif const int MAX_THRESHOLD = 1e5 + 5; // U const int MAX_DIM = 805; const int MAX_CASE = MAX_DIM * MAX_DIM; int M, R, C; string meteo; int U[MAX_DIM][MAX_DIM]; int numero(int l, int c) { return l*C + c; } pii ligCol(int cell) { return {cell/C, cell % C}; } int drepr[MAX_CASE], dsz[MAX_CASE]; void init() { rep(i, 0, R*C) { drepr[i] = i; dsz[i] = 1; } } int find(int a) { if (drepr[a] == a) return a; return drepr[a] = find(drepr[a]); } void unite(int parent, int child) { parent = find(parent), child = find(child); if (parent == child) return; drepr[child] = parent; dsz[parent] += dsz[child]; } int mapChar[256]; int bestSeg[1 << 4]; void calcSeg() { rep(mask, 0, 16) { int best = 0, cur = 0; for (char c : meteo) { if ((1 << mapChar[c]) & mask) { ++cur; } else { cur = 0; } chmax(best, cur); } if (best >= M) best = MAX_THRESHOLD; bestSeg[mask] = best; } } signed main() { ios::sync_with_stdio(false); cin.tie(0); cin >> M >> R >> C; cin >> meteo; meteo.append(meteo); mapChar['N'] = 0, mapChar['W'] = 1, mapChar['E'] = 2, mapChar['S'] = 3; vector<int> deltas(256); deltas['N'] = C, deltas['S'] = -C; // l*C + c if (C > 1) { deltas['W'] = 1, deltas['E'] = -1; } calcSeg(); // rep(mask, 0, 16) { // dbg(mask, bestSeg[mask]); // } rep(i, 0, R) rep(j, 0, C) { cin >> U[i][j]; } init(); priority_queue<pii, vector<pii>, greater<pii>> pq; rep(lig, 0, R) rep(col, 0, C) { if (U[lig][col] != 0) { pq.push({1, numero(lig, col)}); } } auto getVoisins = [&] (int cell) { vector<int> voisins; auto [lig, col] = ligCol(cell); rep(dl, -1, 2) rep(dc, -1, 2) if ((dl==0)^(dc==0)) { int nl = lig+dl, nc = col+dc; if (nl >= 0 && nl < R && nc >= 0 && nc < C && U[nl][nc] != 0) { voisins.push_back(numero(nl, nc)); } } return voisins; }; int best = 1e9; int nbBest = 0; auto updAns = [&] (int proposal) { if (proposal < best) { best = proposal, nbBest = 1; } else if (proposal == best) { ++nbBest; } }; vector<int> isInfected(R*C); vector<bool> mark(R*C, false); int timeInf = 0; auto discover = [&] (int depart) { int compDepart = find(depart); ++timeInf; queue<int> bfs; isInfected[depart] = timeInf; for (int v : getVoisins(depart)) { bfs.push(v); } int nbSeen = 1; // compte depart while (!bfs.empty()) { int cur = bfs.front(); bfs.pop(); if (isInfected[cur] == timeInf) continue; dbg(depart, "voit"s, cur); int mask = 0; for (int v : getVoisins(cur)) { if (isInfected[v] != timeInf) continue; int diff = cur - v; char dir = '~'; for (char c : "NWSE") { if (diff == deltas[c]) dir = c; } assert(dir != '~'); mask += 1 << mapChar[dir]; } auto [lig, col] = ligCol(cur); if (U[lig][col] <= bestSeg[mask]) { int compCur = find(cur); if (compCur != compDepart) { if (mark[compCur]) { mark[compDepart] = true; return; } // merge depart dans cur unite(cur, depart); pq.push({dsz[compCur], compCur}); return; } isInfected[cur] = timeInf; ++nbSeen; for (int v : getVoisins(cur)) { bfs.push(v); } } } // composante stable updAns(nbSeen); dbg(depart, compDepart, "stable"s); mark[compDepart] = true; }; while (!pq.empty()) { auto [szCell, cell] = pq.top(); pq.pop(); if (szCell != dsz[cell]) continue; discover(cell); } cout << best << '\n'; cout << nbBest*best << '\n'; }

컴파일 시 표준 에러 (stderr) 메시지

virus.cpp: In function 'void calcSeg()':
virus.cpp:88:22: warning: array subscript has type 'char' [-Wchar-subscripts]
   88 |    if ((1 << mapChar[c]) & mask) {
      |                      ^
virus.cpp: In lambda function:
virus.cpp:174:26: warning: array subscript has type 'char' [-Wchar-subscripts]
  174 |     mask += 1 << mapChar[dir];
      |                          ^~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...