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)
找到后缀相同的一对单词,后缀的长度可以自己定义,其他单词的后缀不能与这一对相同,使得这样的单词对最多。
Solution: Suffix
先翻转每一个单词(如果不翻转的话取substr的时候就从中间开始取到最后,翻转的话只需要取前面m个字母)。从最长的单词长度依次递减,取每一个单词的后缀,如果两个单词有相同的后缀则把这两个单词去掉,结果+2。因为是从最长的单词长度开始依次取后缀,可以保证后缀相同的单词不被漏掉。
- 时间复杂度:O(N * m)
- m:最长的单词长度
- N:单词个数
- 空间复杂度:O(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>
#include "Print.h"
using namespace std;
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) {
int N, sum = 0, max_len = 0;
cin >> N;
vector<string> words(N);
for (int m = 0; m < N; ++m) {
cin >> words[m];
max_len = max(max_len, static_cast<int>(words[m].size()));
reverse(words[m].begin(), words[m].end());
}
unordered_map<string, int> status;
vector<bool> visited(N, false);
int total = 0;
for (int len = max_len; len > 0; --len) {
for (int m = 0; m < N; ++m) {
if (visited[m] || words[m].size() < len)
continue;
string str = words[m].substr(0, len);
if (status.find(str) != status.end()) {
if (status[str] != -1) {
sum += 2;
visited[status[str]] = true, visited[m] = true;
status[str] = -1;
}
} else
status[str] = m;
}
}
printf("Case #%d: %d\n", case_number, sum);
}
return 0;
}
Golf Gophers (11pts, 21pts)
// TODO