題目: UVa - 11906 - Knight in a War Grid
題目說明
有一個騎士在一個 R x C 的棋盤上移動,從 (0, 0) 開始,每次可以從該點移動到 (±M, ±N) 及 (±N, ±M) 的點,有些點有水則不能跳。如果一個點能從偶數個點跳過來則標記為 偶,如果能從奇數個點跳過來則標記為 奇。求整個棋盤上 奇 跟 偶 的個數。
Input: 第一行為一整數 T,代表有 T 組測資,每組測資的第一行為 4 個整數 R、C、M、N,接下來一行為一個整數 W,代表有 W 個有水的點,接下來 W 行,每行有兩個整數,代表有水的點的座標 **(x, y)**。
Output: 輸出每組測資的 偶、奇 個數。
解題思路
使用 DFS 模擬,紀錄每個點被走到的次數,最後再計算 奇、偶 的個數即可,需要注意的是若 M、N 皆大於 0 且不相同,每次會有 8 個點可以走,若 M、N 相同或是兩者中有一個為 0 則每次只會有 4 個點可以走。還有若是 (0, 0) 除了一開始走到之外都沒有被走到的話會被歸類在 even 裡面。
參考解法
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 
 | #include <iostream>#include <algorithm>
 #include <functional>
 #include <vector>
 
 #define LOOP(n) for(int I = 0; I < n; ++I)
 
 using namespace std;
 
 
 
 static auto __ = []
 {
 ios_base::sync_with_stdio(0);
 cin.tie(0);
 cout.tie(0);
 return 0;
 }();
 
 int main()
 {
 int T, Case = 0;
 cin >> T;
 
 LOOP(T)
 {
 int R, C, M, N, W;
 cin >> R >> C >> M >> N >> W;
 
 
 vector<vector<int>> maps(R, vector<int>(C));
 
 LOOP(W)
 {
 int x, y;
 cin >> x >> y;
 maps[x][y] = -1;
 }
 
 function<void(int, int)> dfs = [&](int x, int y)
 {
 if (x < 0 || x >= R || y < 0 || y >= C || maps[x][y] == -1) return;
 
 
 if (maps[x][y]++ != 0) return;
 
 int _x = M, _y = N;
 LOOP(2)
 {
 dfs(x + _x, y + _y);
 dfs(x - _x, y - _y);
 if (_x && _y)
 {
 dfs(x + _x, y - _y);
 dfs(x - _x, y + _y);
 }
 if (_x == _y) break;
 swap(_x, _y);
 }
 };
 
 dfs(0, 0);
 --maps[0][0];
 
 int odd = 0, even = 0;
 for (auto& v : maps) for (auto& i : v)
 {
 if (i <= 0) continue;
 i & 1 ? ++odd : ++even;
 }
 
 
 if (!maps[0][0]) ++even;
 
 cout << "Case " << ++Case << ": " << even << ' ' << odd << '\n';
 }
 }
 
 | 
參考資料
UVa 11906 - Knight in a War Grid