1 条题解
-
0
题目分析
本题要求根据字符画形式的正方体堆叠图,反推出每个位置的正方体个数,并计算总正方体数量。字符画遵循固定的绘制规则,且满足遮挡关系。
算法思路
核心思想:模式识别 + 高度递推
关键观察:
- 每个正方体的“顶面”具有固定模式
- 从底部向上,正方体高度递减
- 可以利用字符画中的
|符号判断垂直方向的高度
算法流程详解
1. 正方体顶面模板定义
string Up[3] = { "..+---+", "./.../.", "+---+.." };这个模板匹配单个正方体的顶面视图(去掉背景
.后):..+---+ ./ /| +---+ |2. 顶面检测函数
bool check(int x, int y) { for (int i = 0; i < 3; i++) for (int j = 0; j < 7; j++) if (Up[i][j] != Map[x + i][y + j] && Up[i][j] != '.') return 0; return 1; }作用:在位置
(x,y)检测是否存在正方体顶面模式,忽略背景字符.。3. 高度计算函数(递归)
int get(int x, int y) { if (high[x][y]) // 记忆化 return high[x][y]; if (Map[x + 1][y] == '|') // 下方有竖线,说明上面还有正方体 return get(x + 3, y) + 1; return 0; // 底部 }原理:
- 每个正方体在垂直方向占3行字符高度
- 遇到
|符号说明上方还有正方体 - 递归向上计数
4. 主算法流程
步骤1:输入处理
for (int i = 0; i < r; i++) for (int j = 0; j < c; j++) { do ch = getchar(); while (ch != '+' && ch != '/' && ch != '|' && ch != '-' && ch != '.' && ch != ' '); Map[i][j] = ch; }过滤无关字符,只保留有效图形字符。
步骤2:逆向扫描识别
for (int i = r - 1; ~i; i--) // 从下往上扫描 for (int j = c - 1; ~j; j--) // 从右往左扫描 if (check(i, j)) { // 发现正方体顶面 int H = get(i, j + 6); // 计算该位置高度 ans += H; // 累加到总数 // 标记顶点位置的高度(记忆化) for (int x = 0; x < 3; x++) for (int y = 0; y < 7; y++) if (Up[x][y] == '+') high[i + x][j + y] = H; }扫描顺序的重要性:
- 从下往上:确保底部正方体先被处理
- 从右往左:利用题目条件
关键技术与优化
1. 记忆化搜索
if (high[x][y]) return high[x][y];避免重复计算同一位置的高度。
2. 顶点标记
识别到顶面后,标记所有
+顶点的高度,供后续查找使用。3. 字符过滤
只关注关键图形字符,忽略背景和空格。
4. 模板匹配
使用固定模板精确识别正方体顶面。
样例验证
对于样例输入:
14 17 ....+---+---+.... .../ / /|.... ..+---+---+ |.... ./ /| | +---+ +---+ | |/ /| | | +---+---+ | | |/ /| | + +---+---+ | |/| | | | +---+ | | | |/ /| + +---+---+---+ |/. | | | | +.. | | | |/... +---+---+---+....算法过程:
- 从底部向上扫描,识别各个顶面位置
- 对每个顶面,递归计算下方正方体个数
- 累加得到总数:3+3+3+2+2+1=14
输出:
14
复杂度分析
- 时间复杂度:
(每个位置最多检查3×7=21个字符) - 空间复杂度:
对于 的数据范围完全可行
算法优势
- 准确性:基于固定模板匹配,识别精确
- 高效性:记忆化避免重复计算
- 简洁性:核心逻辑清晰,代码量少
- 鲁棒性:适应各种堆叠情况
该算法巧妙利用字符画的规律性,通过模式识别和递推计算,高效解决了从二维字符画反推三维堆叠的问题。
- 1
信息
- ID
- 4657
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者