Official
E - Avoid Knight Attack Editorial
by
E - Avoid Knight Attack Editorial
by
MMNMM
置くことができるマス全体は最大で \(10 ^ {18}-3\) 個などと非常に大きくなる可能性がありますが、置くことができないマスはたかだか \(9M\) 個なので、これをすべて管理することができます。 置くことができないマスをハッシュセットなどで管理し、重複を取り除いて個数を数えることで、この問題を解くことができます。 時間計算量は \(O(M)\) や \(O(M\log M)\) などになります。
実装例は以下のようになります。
#include <iostream>
#include <set>
#include <vector>
int main() {
using namespace std;
int N, M;
cin >> N >> M;
// 置くことができないマスの集合
set<pair<int, int>> bad_cell;
// コマの動く先
vector<pair<int, int>> knight_move{{2, 1}, {1, 2}, {-1, 2}, {-2, 1}, {-2, -1}, {-1, -2}, {1, -2}, {2, -1}};
for (int i = 0; i < M; ++i) {
int x, y;
cin >> x >> y;
bad_cell.emplace(x, y);
for (const auto& [dx, dy] : knight_move)
// 取れる先が存在するマスなら
if (1 <= x + dx && x + dx <= N && 1 <= y + dy && y + dy <= N)
bad_cell.emplace(x + dx, y + dy);
}
// マス全体から置けないマスを引いたものが答え
cout << static_cast<long>(N) * N - size(bad_cell) << endl;
return 0;
}
posted:
last update: