1 条题解
-
0
题意分析
本题要求根据给定的立方体放置规则,判断最终形成的立体图形是否有效,并计算其暴露表面积。核心要点如下:放置规则:第一个立方体放置在地面,后续立方体需依据已放置立方体的相对位置放置,可通过 “L(左)、R(右)、F(前)、B(后)、O(上)、U(下)” 六个方向指定位置。有效性判定:新放置的立方体不能与已有的立方体重叠,且不能放置在地面以下。表面积计算:暴露表面积指不与其他立方体表面接触,也不与地面接触的面的面积总和。
解题思路
坐标与方向处理:建立三维坐标体系,将每个方向映射为坐标变化。例如,“L” 对应x坐标减 1,“R” 对应x坐标加 1,“F” 对应y坐标加 1,“B” 对应y坐标减 1,“O” 对应z坐标加 1,“U” 对应z坐标减 1 。位置记录与有效性检查:使用一个容器(如 C++ 的map或 Python 的字典)记录已放置立方体的坐标。每放置一个新立方体前,检查其坐标是否与已有立方体重复,同时确保其z坐标非负。若不满足条件,则立体图形无效,输出 - 1。表面积计算:初始化第一个立方体的暴露表面积,因为第一个立方体放置在地面,所以其暴露表面积为 5(六个面减去与地面接触的底面)。对于后续每个新放置的立方体,先假设其初始暴露表面积为 6。然后检查其六个相邻位置(前后左右上下)是否有其他立方体,若有则减少相应的暴露面(每有一个相邻立方体,暴露面减少 1)。若新立方体放置在地面上,还需减去底面的暴露面积。最后将新立方体的有效暴露表面积累加到总暴露表面积中。输出结果:若整个放置过程中未出现无效情况,输出最终的总暴露表面积;若存在无效放置,则输出 - 1。
代码
#include <vector> #include <map> #include <string> using namespace std; struct Point { int x, y, z; bool operator<(const Point& other) const { if (x != other.x) return x < other.x; if (y != other.y) return y < other.y; return z < other.z; } }; int main() { int n; cin >> n; map<Point, bool> placed; vector<Point> coords; Point first = {0, 0, 0}; coords.push_back(first); placed[first] = true; int currentSurface = 5; // 第一个立方体在地面上,少一个底面 bool valid = true; for (int i = 1; i < n; ++i) { int j; string dir; cin >> j >> dir; --j; // 转换为0-索引 if (j < 0 || j >= (int)coords.size()) { valid = false; break; } Point prev = coords[j]; Point newPoint = prev; if (dir == "L") --newPoint.x; else if (dir == "R") ++newPoint.x; else if (dir == "F") ++newPoint.y; else if (dir == "B") --newPoint.y; else if (dir == "O") ++newPoint.z; else if (dir == "U") --newPoint.z; else { valid = false; break; } if (newPoint.z < 0) { valid = false; break; } if (placed.find(newPoint) != placed.end()) { valid = false; break; } placed[newPoint] = true; coords.push_back(newPoint); int newSurface = 6; // 检查六个相邻位置 Point adj[6] = { {newPoint.x-1, newPoint.y, newPoint.z}, {newPoint.x+1, newPoint.y, newPoint.z}, {newPoint.x, newPoint.y+1, newPoint.z}, {newPoint.x, newPoint.y-1, newPoint.z}, {newPoint.x, newPoint.y, newPoint.z+1}, {newPoint.x, newPoint.y, newPoint.z-1} }; for (int k = 0; k < 6; ++k) { if (placed.find(adj[k]) != placed.end()) { --newSurface; } } if (newPoint.z == 0) { --newSurface; } currentSurface += newSurface; } cout << (valid ? currentSurface : -1) << endl; return 0; }
- 1
信息
- ID
- 1181
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 3
- 已通过
- 1
- 上传者