# Google Kick Start 2019 Round C 题解

# Problem A - Wiggie Walk (opens new window)

# 题解

• 给定起始位置（行、列）和方向，找出下一个空位置
• 将走到的新位置加入所在行和列的区间集合

#include <algorithm>
#include <iostream>
#include <set>
#include <vector>

using namespace std;

// Validated by [LC57](https://leetcode.cn/problems/insert-interval/).
// Need to change "r + 1" to "r" due to difference in the definition of segment.
void insert(set<pair<int, int>> &s, pair<int, int> p) {
s.insert(p);
auto it = s.lower_bound(p);
if (it != s.begin())
--it;
int l = it->first, r = it->second;
++it;
while (l <= p.first) {
if (it == s.end())
break;
if (it->first > r + 1) {
l = it->first;
r = it->second;
++it;
} else {
s.erase({l, r});
r = max(r, it->second);
++it;
s.erase(prev(it));
s.insert({l, r});
}
}
}

int find(set<pair<int, int>> &s, int pos, int type) {
if (type) {
auto it = s.lower_bound({pos, pos});
if (it != s.end() && it->first == pos)
return it->second + 1;
--it;
return it->second + 1;
} else {
auto it = s.lower_bound({pos, pos});
if (it != s.end() && it->first == pos)
return pos - 1;
--it;
return it->first - 1;
}
}

int main() {
int t;
cin >> t;
for (int case_num = 1; case_num <= t; ++case_num) {
int n, r, c, sr, sc;
string s;
cin >> n >> r >> c >> sr >> sc >> s;
cout << "Case #" << case_num << ": ";
vector<set<pair<int, int>>> row(r + 1), col(c + 1);
insert(row[sr], {sc, sc});
insert(col[sc], {sr, sr});
for (char c : s) {
switch (c) {
case 'W':
sc = find(row[sr], sc, 0);
break;
case 'E':
sc = find(row[sr], sc, 1);
break;
case 'N':
sr = find(col[sc], sr, 0);
break;
default:
sr = find(col[sc], sr, 1);
break;
}
insert(row[sr], {sc, sc});
insert(col[sc], {sr, sr});
}
cout << sr << " " << sc << endl;
}
}

1
2
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
78
79
80
81

# Problem B - Circuit Board (opens new window)

# 题解

#include <iostream>
#include <set>
#include <stack>
#include <vector>

using namespace std;

int main() {
int t;
cin >> t;
for (int case_num = 1; case_num <= t; ++case_num) {
int r, c, k;
cin >> r >> c >> k;
cout << "Case #" << case_num << ": ";
vector<vector<int>> v(r + 1, vector<int>(c + 1));
for (int i = 1; i <= r; ++i)
for (int j = 1; j <= c; ++j)
cin >> v[i][j];
vector<vector<int>> f(r + 2, vector<int>(c + 1));
for (int i = 1; i <= r; ++i) {
set<pair<int, int>> s;
int l = 1;
for (int j = 1; j <= c; ++j) {
s.emplace(v[i][j], j);
while (s.rbegin()->first - s.begin()->first > k) {
if (s.rbegin()->second < s.begin()->second) {
l = max(l, s.rbegin()->second + 1);
s.erase(*s.rbegin());
} else {
l = max(l, s.begin()->second + 1);
s.erase(*s.begin());
}
}
f[i][j] = j - l + 1;
}
}
int ans = 0;
for (int j = 1; j <= c; ++j) {
stack<pair<int, int>> st;
for (int i = 1; i <= r + 1; ++i) {
int l = i;
while (!st.empty() && f[i][j] < st.top().first) {
ans = max(ans, st.top().first * (i - st.top().second));
l = st.top().second;
st.pop();
}
if (st.empty() || st.top().first < f[i][j])
st.emplace(f[i][j], l);
}
}
cout << ans << endl;
}
}

1
2
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

#include <deque>
#include <iostream>
#include <stack>
#include <vector>

using namespace std;

int main() {
int t;
cin >> t;
for (int case_num = 1; case_num <= t; ++case_num) {
int r, c, k;
cin >> r >> c >> k;
cout << "Case #" << case_num << ": ";
vector<vector<int>> v(r + 1, vector<int>(c + 1));
for (int i = 1; i <= r; ++i)
for (int j = 1; j <= c; ++j)
cin >> v[i][j];
vector<vector<int>> f(r + 2, vector<int>(c + 1));
for (int i = 1; i <= r; ++i) {
deque<pair<int, int>> asc, desc;
int l = 1;
for (int j = 1; j <= c; ++j) {
while (!asc.empty() && asc.back().first >= v[i][j])
asc.pop_back();
while (!asc.empty() && v[i][j] - asc.front().first > k) {
l = max(l, asc.front().second + 1);
asc.pop_front();
}
asc.emplace_back(v[i][j], j);
while (!desc.empty() && desc.back().first <= v[i][j])
desc.pop_back();
while (!desc.empty() && desc.front().first - v[i][j] > k) {
l = max(l, desc.front().second + 1);
desc.pop_front();
}
desc.emplace_back(v[i][j], j);
f[i][j] = j - l + 1;
}
}
int ans = 0;
for (int j = 1; j <= c; ++j) {
stack<pair<int, int>> st;
for (int i = 1; i <= r + 1; ++i) {
int l = i;
while (!st.empty() && f[i][j] < st.top().first) {
ans = max(ans, st.top().first * (i - st.top().second));
l = st.top().second;
st.pop();
}
if (st.empty() || st.top().first < f[i][j])
st.emplace(f[i][j], l);
}
}
cout << ans << endl;
}
}

1
2
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

# Problem C - Catch Some (opens new window)

# 题解

#include <algorithm>
#include <iostream>
#include <map>
#include <vector>

using namespace std;

int main() {
int t;
cin >> t;
for (int case_num = 1; case_num <= t; ++case_num) {
cout << "Case #" << case_num << ": ";
int n, k;
cin >> n >> k;
vector<pair<int, int>> dogs(n);
for (int i = 0; i < n; ++i)
cin >> dogs[i].first;
for (int i = 0; i < n; ++i)
cin >> dogs[i].second;
sort(dogs.begin(), dogs.end());
map<int, vector<int>> c;
for (auto dog : dogs)
c[dog.second].emplace_back(dog.first);
vector<vector<int>> vc;
for (auto p : c)
vc.push_back(p.second);
vector<vector<int>> dp(k + 1, vector<int>(2, 1e9));
dp[0][0] = 0;
for (int i = 0; i < vc.size(); ++i) {
vector<vector<int>> ndp(dp);
for (int j = 0; j < vc[i].size(); ++j) {
for (int s = k; s >= j + 1; --s) {
ndp[s][0] = min(ndp[s][0], dp[s - j - 1][0] + 2 * vc[i][j]);
ndp[s][1] = min(ndp[s][1], min(dp[s - j - 1][1] + 2 * vc[i][j],
dp[s - j - 1][0] + vc[i][j]));
}
}
dp = move(ndp);
}
cout << dp[k][1] << endl;
}
}

1
2
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