Code Jam 2019 Qualification Round
Foregone Solution (6pts, 10pts, 1pts)
将一个带有数字4的数拆分为两个不带数字4的数。
Solution: Construction
输入的数一定带有数字4,对于每一位上的数字4,我们可以将其拆分为2+2(或1+3)的两个数。输入数据最大是10的100次方,所以我们可以将其作为字符串处理。
- 时间复杂度:O(n)
- 空间复杂度:O(1)
// C++
#include <iostream>
#include <cmath>
#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 main() {
int T;
cin >> T;
for (int t = 1; t <= T; ++t) {
string N;
cin >> N;
string a, b;
for (auto c:N) {
a += c == '4' ? '2' : c;
b += c == '4' ? '2' : '0';
}
while (a[0] == '0')
a.erase(a.begin());
while (b[0] == '0')
b.erase(b.begin());
cout << "Case #" << t << ": " << a << " " << b << endl;
}
}
You Can Go Your Own Way (5pts, 9pts, 10pts)
在n*n的矩阵里从(0,0)走到(n-1,n-1),只能向右或向下走。矩阵里有一条已有的路径,不能与该路径有重合。最常规的做法是DFS/BFS,时间复杂度为O(n^2)。
Solution: Mirror
因为只有一条已知路径,我们可以将其以对角线作镜像,得到的新路径一定与原路径没有重合。
- 时间复杂度:O(2 * n - 2)
- 空间复杂度:O(1)
// C++
#include <iostream>
#include <cmath>
#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 main() {
int T;
cin >> T;
for (int t = 1; t <= T; ++t) {
int N;
string str;
cin >> N >> str;
for (int i = 0; i < N * 2 - 2; ++i)
str[i] = str[i] == 'E' ? 'S' : 'E';
cout << "Case #" << t << ": " << str << endl;
}
}
Cryptopangrams (10pts, 15pts)
输入上限N和一个长为L的数组product,数组里的每一个数都是一个长为L+1的质数数组res里的相邻质数的乘积。质数数组里一共只有26个质数,返回将这26个质数排序后分别映射为A-Z的结果。对于比较小的N,可以把小于等于N的所有质数保存下来,计算出product[0]是哪两个质数的乘积,再计算出product[1]是哪两个质数的乘积,得到res[1],再依次计算质数数组res里的其他数。在N比较大的时候时间和空间占用都会很高。
Solution: Greatest Common Denominator
相较于先找到所有质数再找到product[0]是哪两个质数的乘积,我们可以使用小学学过的辗转相除法来求出这个质数,这样可以非常有效地降低时间和空间消耗。
这道题测试用例的N最大值是10的100次方,用C++需要自己处理大数乘法(C++最大只支持128位的int型数)。
- 时间复杂度:O(L)
- 空间复杂度:O(L)
# Python 3
def GCD(a: int, b: int) -> int:
if b == 0:
return a
return GCD(b, a % b)
T = int(input())
for t in range(1, T + 1):
N, L = map(int, input().split())
product = list(map(int, input().split()))
res = [0 for _ in range(L + 1)]
pos = -1
for i in range(L - 1):
if product[i] != product[i + 1]:
res[i + 1] = GCD(product[i], product[i + 1])
pos = i + 1
break
for i in range(pos + 1, L + 1):
res[i] = product[i - 1] // res[i - 1]
for i in range(pos - 1, -1, -1):
res[i] = product[i] // res[i + 1]
match = []
for m in res:
if m not in match:
match.append(m)
match.sort()
ret = [chr(match.index(res[i]) + ord('A')) for i in range(len(res))]
print("Case #{t}: {str}".format(t=t, str="".join(ret)))
Dat Bae (14pts, 20pts)
// TODO