Kick Start 2019 Round C
Wiggle Walk (6pts, 12pts)
在一个R * C的矩阵里面移动,遇到已经走过的格子直接跳过。数据保证移动时不会超出给定的矩阵。
Solution: Simulation
用一个visited数组记录已经走过的格子,遇到走过的格子则直接跳过往后遍历。讲道理这个方法时间复杂度是过不了Hidden Test Set的,但是我也不知道为什么就过了。
- 时间复杂度:O(n^2)
- 空间复杂度:O(n^2)
// 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;
vector<vector<bool>> visited(50001, vector<bool>(50001, false));
void Forward(char &p, int &r, int &c) {
if (p == 'E') {
while (visited[r][c + 1])
++c;
visited[r][++c] = true;
} else if (p == 'W') {
while (visited[r][c - 1])
--c;
visited[r][--c] = true;
} else if (p == 'N') {
while (visited[r - 1][c])
--r;
visited[--r][c] = true;
} else if (p == 'S') {
while (visited[r + 1][c])
++r;
visited[++r][c] = true;
}
}
void solve(const int &t) {
int n, R, C, r, c;
string str;
scanf("%d %d %d %d %d", &n, &R, &C, &r, &c);
cin >> str;
visited = vector<vector<bool>>(50001, vector<bool>(50001, false));
visited[r][c] = true;
for (int i = 0; i < n; ++i)
Forward(str[i], r, c);
printf("Case #%d: %d %d\n", t, r, c);
}
int main() {
int T;
scanf("%d", &T);
for (int t = 1; t <= T; ++t)
solve(t);
return 0;
}
Circuit Board (14pts, 20pts)
在矩阵里找到每一行最大值与最小值不超过K的最大子矩阵。
Solution: Dynamic Programming
定义一个矩阵len[r][c]来保存格子r, c在r行上符合条件的最长数组。因为题目要求是需要保证每一行的最大值与最小值不超过K,行与行之间是没有关系的,所以对于每一个格子,遍历该列上的所有格子,找到这些格子能够到达的最远的位置,取最小值,用当前的高度乘最远位置就能得到答案。
- 时间复杂度:O(RRC)
- 空间复杂度:O(RC)
// 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;
void solve(const int &t) {
int R, C, K;
scanf("%d %d %d", &R, &C, &K);
vector<vector<int>> len(301, vector<int>(301, 1)), matrix(301, vector<int>(301));
for (int r = 0; r < R; ++r)
for (int c = 0; c < C; ++c)
scanf("%d", &matrix[r][c]);
for (int r = 0; r < R; ++r) {
for (int c = 0; c < C; ++c) {
int i = c - 1, current_max = matrix[r][c], current_min = matrix[r][c];
while (i >= 0) {
current_max = max(current_max, matrix[r][i]);
current_min = min(current_min, matrix[r][i]);
if (current_max - current_min > K)
break;
--i;
}
len[r][c] = c - i;
}
}
int res = 1;
for (int r = 0; r < R; ++r) {
for (int c = 0; c < C; ++c) {
int min_c = len[r][c];
for (int line = r; line >= 0; --line) {
min_c = min(min_c, len[line][c]);
res = max(res, min_c * (r - line + 1));
}
}
}
printf("Case #%d: %d\n", t, res);
}
int main() {
int T;
scanf("%d", &T);
for (int t = 1; t <= T; ++t)
solve(t);
return 0;
}
Catch Some (18pts, 30pts)
// TODO