結果
問題 | No.340 雪の足跡 |
ユーザー | yudedako |
提出日時 | 2016-02-04 10:14:45 |
言語 | C++11 (gcc 11.4.0) |
結果 |
TLE
|
実行時間 | - |
コード長 | 4,684 bytes |
コンパイル時間 | 725 ms |
コンパイル使用メモリ | 75,568 KB |
実行使用メモリ | 20,352 KB |
最終ジャッジ日時 | 2024-09-21 20:16:16 |
合計ジャッジ時間 | 4,623 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge1 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 1 ms
10,752 KB |
testcase_01 | AC | 1 ms
5,376 KB |
testcase_02 | AC | 1 ms
5,376 KB |
testcase_03 | AC | 1 ms
5,376 KB |
testcase_04 | AC | 2 ms
5,376 KB |
testcase_05 | AC | 2 ms
5,376 KB |
testcase_06 | AC | 1 ms
5,376 KB |
testcase_07 | AC | 1 ms
5,376 KB |
testcase_08 | AC | 1 ms
5,376 KB |
testcase_09 | AC | 1 ms
5,376 KB |
testcase_10 | AC | 1 ms
5,376 KB |
testcase_11 | AC | 3 ms
5,376 KB |
testcase_12 | AC | 3 ms
5,376 KB |
testcase_13 | AC | 5 ms
5,376 KB |
testcase_14 | AC | 57 ms
7,680 KB |
testcase_15 | AC | 70 ms
7,972 KB |
testcase_16 | AC | 40 ms
5,376 KB |
testcase_17 | AC | 92 ms
8,704 KB |
testcase_18 | AC | 77 ms
8,824 KB |
testcase_19 | AC | 91 ms
8,832 KB |
testcase_20 | TLE | - |
testcase_21 | -- | - |
testcase_22 | -- | - |
testcase_23 | -- | - |
testcase_24 | -- | - |
testcase_25 | -- | - |
testcase_26 | -- | - |
testcase_27 | -- | - |
testcase_28 | -- | - |
testcase_29 | -- | - |
testcase_30 | -- | - |
testcase_31 | -- | - |
testcase_32 | -- | - |
testcase_33 | -- | - |
testcase_34 | -- | - |
testcase_35 | -- | - |
testcase_36 | -- | - |
ソースコード
#include <vector> #include <iostream> #include <climits> template <class T> class Heap { public: Heap(const int &n) :vector(n + 1), idx(0) {}; void insert_value(const T &val) { vector.at(++idx) = val; bottom_up_normalize(idx); } T pop() { auto res = vector.at(1); vector.at(1) = vector.at(idx); vector.at(idx--) = vector.back(); top_down_normalize(1); return res; } int size() const { return idx; } T top() const { return vector.at(1); } private: std::vector<T> vector; int idx; void bottom_up_normalize(const int &i) { if (i != 1) { if (vector.at(i) < vector.at(i / 2)) { auto temp = vector.at(i / 2); vector.at(i / 2) = vector.at(i); vector.at(i) = temp; bottom_up_normalize(i / 2); } } } void top_down_normalize(const int &i) { int next = get(i); if (vector.at(next) < vector.at(i)) { auto temp = vector.at(next); vector.at(next) = vector.at(i); vector.at(i) = temp; top_down_normalize(next); } } int get(const int &n) const { if (n * 2 + 1 <= idx) { return (vector.at(n * 2 + 1) < vector.at(n * 2)) ? n * 2 + 1 : n * 2; } else if (n * 2 <= idx) { return n * 2; } else { return n; } } }; class Cell { public: Cell(const int &ax = 0, const int &ay = 0) :state{ 0 }, x{ ax }, y{ ay } {}; bool is_neighbor(const Cell &other) const { return (abs(x - other.x) + abs(y - other.y)) == 1; } void set_path(Cell &from) { if (is_neighbor(from)) { if (x == from.x) { if (y > from.y) { state |= up; from.state |= down; } else { state |= down; from.state |= up; } } else { if (x > from.x) { state |= left; from.state |= right; } else { state |= right; from.state |= left; } } } } std::vector<std::pair<int, int>> get_neighbor() const { std::vector<std::pair<int, int>> res; for (const auto &p : { std::make_pair(x + 1, y), std::make_pair(x - 1, y), std::make_pair(x, y + 1), std::make_pair(x, y - 1) }) { if (has_path(p.first, p.second)) { res.push_back(p); } } return res; } private: enum { right = 1, down = 2, left = 4, up = 8 }; int state; int x, y; int abs(const int &n) const { return n > 0 ? n : -n; } bool has_path(const int &cellx, const int &celly) const { if ((abs(x - cellx) + abs(y - celly)) == 1) { if (x == cellx) { if (y > celly) { return (state & up) != 0; } else { return (state & down) != 0; } } else { if (x > cellx) { return (state & left) != 0; } else { return (state & right) != 0; } } } else { return false; } } }; struct Reach_time { int x, y; int time; Reach_time(const int &ax = 0, const int &ay = 0, const int &at = 0) :x{ ax }, y{ ay }, time{ at } {}; bool operator<(const Reach_time &other) const { return time < other.time; } }; int daijkstra(const std::vector<std::vector<Cell>> &map) { Heap<Reach_time> heap(map.size() * map.at(0).size() * 4); std::vector<std::vector<int>> memo(map.size(), std::vector<int>(map.at(0).size(), INT_MAX)); heap.insert_value(Reach_time(0, 0, 0)); memo.at(0).at(0) = 0; while (((heap.top().x != map.at(0).size() - 1) || (heap.top().y != map.size() - 1)) && heap.size() != 0) { auto rtime = heap.pop(); const auto &cell = map.at(rtime.y).at(rtime.x); for (const auto &neighbor : cell.get_neighbor()) { if (memo.at(neighbor.second).at(neighbor.first) > rtime.time + 1) { memo.at(neighbor.second).at(neighbor.first) = rtime.time + 1; heap.insert_value(Reach_time(neighbor.first, neighbor.second, rtime.time + 1)); } } } if (heap.size() == 0) { return -1; } else { return heap.top().time; } } int main() { int w, h, n; std::cin >> w >> h >> n; std::vector<std::vector<Cell>> map(h, std::vector<Cell>(w)); for (auto y = 0; y < h; ++y) { for (auto x = 0; x < w; ++x) { map.at(y).at(x) = Cell(x, y); } } for (auto i = 0; i < n; ++i) { int m; std::cin >> m; int prev; std::cin >> prev; for (int b; m > 0; --m) { std::cin >> b; if (prev % w == b % w) { auto min = prev / w > b / w ? b / w : prev / w; auto max = prev / w > b / w ? prev / w : b / w; for (; min < max; ++min) { map.at(min).at(prev % w).set_path(map.at(min + 1).at(prev % w)); } } else { auto min = prev % w > b % w ? b % w : prev % w; auto max = prev % w > b % w ? prev % w : b % w; for (; min < max; ++min) { map.at(prev / w).at(min).set_path(map.at(prev / w).at(min + 1)); } } prev = b; } } auto res = daijkstra(map); if (res == -1) { std::cout << "Odekakedekinai.." << std::endl; } else { std::cout << res << std::endl; } return 0; }