1 条题解

  • 0
    @ 2025-5-21 12:46:27

    题意分析

    本题要求根据给定的立方体放置规则,判断最终形成的立体图形是否有效,并计算其暴露表面积。核心要点如下:放置规则:第一个立方体放置在地面,后续立方体需依据已放置立方体的相对位置放置,可通过 “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
    上传者