제출 #352011

#제출 시각아이디문제언어결과실행 시간메모리
352011KoD바이러스 (JOI19_virus)C++17
100 / 100
1201 ms48228 KiB
#line 1 "main.cpp" /** * @title Template */ #include <iostream> #include <algorithm> #include <utility> #include <numeric> #include <vector> #include <array> #include <cassert> #line 2 "/Users/kodamankod/Desktop/cpp_programming/Library/other/range.cpp" #line 4 "/Users/kodamankod/Desktop/cpp_programming/Library/other/range.cpp" class range { struct iter { std::size_t itr; constexpr iter(std::size_t pos) noexcept: itr(pos) { } constexpr void operator ++ () noexcept { ++itr; } constexpr bool operator != (iter other) const noexcept { return itr != other.itr; } constexpr std::size_t operator * () const noexcept { return itr; } }; struct reviter { std::size_t itr; constexpr reviter(std::size_t pos) noexcept: itr(pos) { } constexpr void operator ++ () noexcept { --itr; } constexpr bool operator != (reviter other) const noexcept { return itr != other.itr; } constexpr std::size_t operator * () const noexcept { return itr; } }; const iter first, last; public: constexpr range(std::size_t first, std::size_t last) noexcept: first(first), last(std::max(first, last)) { } constexpr iter begin() const noexcept { return first; } constexpr iter end() const noexcept { return last; } constexpr reviter rbegin() const noexcept { return reviter(*last - 1); } constexpr reviter rend() const noexcept { return reviter(*first - 1); } }; /** * @title Range */ #line 2 "/Users/kodamankod/Desktop/cpp_programming/Library/other/random_number.cpp" #include <cstdint> #include <random> #include <chrono> #line 7 "/Users/kodamankod/Desktop/cpp_programming/Library/other/random_number.cpp" #include <type_traits> uint64_t engine() { static uint64_t result = static_cast<uint64_t>(std::chrono::system_clock::now().time_since_epoch().count()); result ^= result << 5; result ^= result >> 13; result ^= result << 7; return result; } template <class Integer> typename std::enable_if<std::is_integral<Integer>::value, Integer>::type random_number(Integer lower, Integer upper) { static std::default_random_engine gen(engine()); return std::uniform_int_distribution<Integer>(lower, upper)(gen); } template <class Real> typename std::enable_if<!std::is_integral<Real>::value, Real>::type random_number(Real lower, Real upper) { static std::default_random_engine gen(engine()); return std::uniform_real_distribution<Real>(lower, upper)(gen); } /** * @title Random Number */ #line 16 "main.cpp" using i32 = std::int32_t; using i64 = std::int64_t; using u32 = std::uint32_t; using u64 = std::uint64_t; using isize = std::ptrdiff_t; using usize = std::size_t; template <class T> using Vec = std::vector<T>; constexpr usize MAX = 800 * 800 + 5; constexpr std::array<char, 4> LETTER = { 'W', 'E', 'N', 'S' }; constexpr std::array<isize, 4> di = { 0, 0, -1, 1 }; constexpr std::array<isize, 4> dj = { -1, 1, 0, 0 }; int main() { usize M, R, C; std::cin >> M >> R >> C; std::string D; std::cin >> D; { const auto str = D; while (D.size() < 200000) { D += str; } } Vec<Vec<usize>> strength(R, Vec<usize>(C)); for (auto &v: strength) { for (auto &x: v) { std::cin >> x; } } std::array<usize, (1 << 4)> max{}; for (auto set: range(0, 1 << 4)) { usize cur = 0; for (const auto c: D) { bool ok = false; for (auto i: range(0, 4)) { if ((set >> i & 1) == 1 && LETTER[i] == c) { ok = true; break; } } if (ok) { cur += 1; } else { cur = 0; } max[set] = std::max(max[set], cur); } } Vec<std::pair<usize, usize>> cell(R * C); for (auto i: range(0, R)) { for (auto j: range(0, C)) { cell[i * C + j] = std::make_pair(i, j); } } { std::default_random_engine gen(engine()); std::shuffle(cell.begin(), cell.end(), gen); } Vec<Vec<usize>> ans(R, Vec<usize>(C, MAX)); Vec<Vec<bool>> visited(R, Vec<bool>(C)); Vec<Vec<bool>> done(R, Vec<bool>(C)); const auto inside = [&](const isize i, const isize j) { return 0 <= i && i < (isize) R && 0 <= j && j < (isize) C; }; const auto check = [&](const isize i, const isize j) { if (!inside(i, j) || strength[i][j] == 0) { return false; } usize set = 0; for (auto k: range(0, 4)) { const auto ni = i + di[k]; const auto nj = j + dj[k]; if (inside(ni, nj) && visited[ni][nj]) { set |= 1 << k; } } return max[set] >= strength[i][j]; }; for (const auto [si, sj]: cell) { if (strength[si][sj] == 0) { continue; } done[si][sj] = true; Vec<std::pair<isize, isize>> que; visited[si][sj] = true; que.emplace_back(si, sj); bool consider = true; for (usize idx = 0; idx < que.size(); ++idx) { const auto [i, j] = que[idx]; for (auto k: range(0, 4)) { const auto ni = i + di[k]; const auto nj = j + dj[k]; if (check(ni, nj) && !visited[ni][nj]) { if (done[ni][nj]) { consider = false; break; } visited[ni][nj] = true; que.emplace_back(ni, nj); } } if (!consider) { break; } } if (consider) { for (const auto [i, j]: que) { ans[i][j] = std::min(ans[i][j], que.size()); } } for (const auto [i, j]: que) { visited[i][j] = false; } } usize val = MAX, cnt = 0; for (const auto &v: ans) { for (const auto x: v) { if (val > x) { val = x; cnt = 0; } if (val == x) { cnt += 1; } } } std::cout << val << '\n'; std::cout << cnt << '\n'; return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...