【LeetCode-16-22】解题报告(模拟,集合)

原始题目

一只蚂蚁坐在由白色和黑色方格构成的无限网格上。开始时,网格全白,蚂蚁面向右侧。每行走一步,蚂蚁执行以下操作。

  1. 如果在白色方格上,则翻转方格的颜色,向右(顺时针)转 90 度,并向前移动一个单位。
  2. 如果在黑色方格上,则翻转方格的颜色,向左(逆时针方向)转 90 度,并向前移动一个单位。

编写程序来模拟蚂蚁执行的前 K 个动作,并返回最终的网格。

网格由数组表示,每个元素是一个字符串,代表网格中的一行,黑色方格由  'X'  表示,白色方格由  '_'  表示,蚂蚁所在的位置由  'L', 'U', 'R', 'D'  表示,分别表示蚂蚁   左、上、右、下 的朝向。只需要返回能够包含蚂蚁走过的所有方格的最小矩形。

解题思路

无需维护整个地图状态,用一个点集合来维护黑色方格,绘图时确定边界为\([min{now,p (p \in S)}, max{now, p (p \in S)}\)

需要特别注意的是 C++构造输出答案时应用了 vector<string> ans(rows,temp)构造方式,否则超时(逐个 push_back)。

解题代码

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
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;

#define rep(i, a, n) for (int i = a; i < n; ++i)
#define per(i, a, n) for (int i = n - 1; i >= a; --i)
#define fi first
#define se second
#define pb push_back
#define np next_permutation
#define mp make_pair
#define all(x) x.begin(), x.end()


class Solution {
public:
vector<string> printKMoves(int K)
{
int ax, ay;
int dir[4][2] = { { -1, 0 }, { 0, -1 }, { 1, 0 }, { 0, 1 } };
int dirid;
char mmp[4] = { 'L', 'U', 'R', 'D' };
set<pii> pos;
ax = ay = 0;
pos.clear();
dirid = 2;
rep(i, 0, K)
{
if (pos.count(mp(ax, ay)) == 0) {
// bai
dirid = (dirid + 1) % 4;
pos.insert(mp(ax, ay));
} else {
dirid = (dirid + 3) % 4;
pos.erase(mp(ax, ay));
}
ax = ax + dir[dirid][0];
ay = ay + dir[dirid][1];
}

int vx_max = ax;
int vx_min = ax;
int vy_max = ay;
int vy_min = ay;
for (auto i : pos) {
vx_max = max(i.first, vx_max);
vx_min = min(i.first, vx_min);
vy_max = max(i.second, vy_max);
vy_min = min(i.second, vy_min);
}
int rows = vy_max - vy_min + 1;
int cols = vx_max - vx_min + 1;
string temp;
for (int i = 0; i < cols; i++)
temp.push_back('_');
vector<string> ans(rows, temp);
for (auto it = pos.begin(); it != pos.end(); it++) {

ans[it->second - vy_min][it->first - vx_min] = 'X';
}
ans[ay - vy_min][ax - vx_min] = mmp[dirid];

return ans;
}
};