Code Jam 2019 Round 1A Pylons (8pts, 23pts) 在m*n的网格里移动,每次移动后的位置不能与之前的位置在同一行/列/对角线上。
Solution: BackTracking 类似于八皇后问题,不过每次的限制条件只和上一个位置有关,可以用回溯解决。
时间复杂度:O(m^2 * n^2) 空间复杂度:O(m * n) // C++ #include <iostream> #include <cmath> #include <cstdio> #include <math.h> #include <limits> #include <algorithm> #include <vector> #include <stack> #include <queue> #include <string> #include <map> #include <set> #include <unordered_map> #include <unordered_set> using namespace std; int m, n; bool BackTracking(int t, int i, int j, vector<vector<bool>> &visited, vector<vector<int>> &res) { visited[i][j] = true; res[t] = {i, j}; if (t + 1 == m * n) return true; for (int x = 0; x < m; ++x) { for (int y = 0; y < n; ++y) { int r = (x + i) % m, c = (y + j) % n; if (!visited[r][c] && r != i && c != j && r + c != i + j && r - c != i - j && BackTracking(t + 1, r, c, visited, res)) return true; } } visited[i][j] = false; return false; } int main() { int total_test_case_number; cin >> total_test_case_number; for (int case_number = 1; case_number <= total_test_case_number; ++case_number) { bool rev = false; cin >> m >> n; if (m > n) { rev = true; swap(n, m); } vector<vector<bool>> visited(m, vector<bool>(n, false)); vector<vector<int>> res(m * n, vector<int>()); printf("Case #%d: ", case_number); if (BackTracking(0, 0, 0, visited, res)) { printf("POSSIBLE\n"); for (int i = 0; i < m * n; ++i) if (!rev) printf("%d %d\n", res[i][0] + 1, res[i][1] + 1); else printf("%d %d\n", res[i][1] + 1, res[i][0] + 1); } else printf("IMPOSSIBLE\n"); } return 0; } Alien Rhyme (10pts, 27pts) 找到后缀相同的一对单词,后缀的长度可以自己定义,其他单词的后缀不能与这一对相同,使得这样的单词对最多。
...