首页 > 试题广场 >

三视图

[编程题]三视图
  • 热度指数:1 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
Etéreo 拿出家里的许多的立方体积木,堆成了一个三维空间中的模型。既然你高考选了技术, 那想必你一定想知道,这个模型的三视图是什么吧! 

图中, 轴、 轴和  轴的方向已经标明。现在规定,图中的红色面为主视面,蓝色面为右视面(注意输出中应为左视而非右视),黄色面为俯视面。具体方向可以观察样例。 

输入描述:
第一行四个数  ,表示该三维空间大小为  ,且有  个立方体。 
接下去  行,每行三个整数  ,表示其位置坐标。


输出描述:
输出共  行,前  行每行  个字符,输出正视图及左视图,两幅图之间有一列空格;接下去输出一个空行;再接下去  行,每行  个字符,表示俯视图。
其中  表示空,  表示有立方体。
示例1

输入

2 2 2 2
1 1 1
2 2 2

输出

.x .x
x. x.

x.
.x
示例2

输入

3 3 3 3
1 1 2
2 1 1
1 2 1

输出

... ...
x.. x..
xx. xx.

xx.
x..
...

说明

这里可以把图片拉出去放大看哦~

备注:


纯模拟
发表于 今天 00:20:26 回复(0)
好简单的模拟题,猫猫觉得不用讲了喵
#include <bits/stdc++.h>
using namespace std;

int main() {
    int x,y,z;cin >> x >> y >> z;
    int n;cin >> n;
    vector<vector<bool>> xy(x,vector<bool>(y,0));
    vector<vector<bool>> yz(y,vector<bool>(z,0));
    vector<vector<bool>> xz(x,vector<bool>(z,0));
    for(int i=0;i<n;i++)
    {
        int a,b,c;cin >> a >> b >> c;
        xy[a-1][b-1]=1;
        yz[b-1][c-1]=1;
        xz[a-1][c-1]=1;
    }
    for(int i=y-1;i>=0;i--)
    {
        for(int j=0;j<x;j++)
        {
            if(xy[j][i]) cout << 'x';
            else cout << '.';
        }
        cout << ' ';
        for(int j=0;j<z;j++)
        {
            if(yz[i][j]) cout << 'x';
            else cout << '.';
        }
        cout << '\n';
    }
    cout << '\n';
    for(int i=0;i<z;i++)
    {
        for(int j=0;j<x;j++)
        {
            if(xz[j][i]) cout << 'x';
            else cout << '.';
        }
        cout << '\n';
    }
}
/*
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣤⣤⡀⣀⣠⣤⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣀⡀⢀⣴⣾⣷⣶⣾⣿⣿⣿⣿⣿⣿⣿⣿⣷⣾⣿⣷⣦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣾⣿⣿⣿⣿⣿⣿⣿⠿⠛⠛⠉⠉⠉⠉⠉⠉⠛⠻⠿⣿⣿⣿⣿⣿⣶⣤⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⢠⣾⣿⣿⣿⡿⠿⠛⠉⠉⠉⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠙⠿⣿⣿⣿⣷⣄⡀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⣀⣿⣿⣿⠟⠁⠀⠀⠀⠀⠀⠀⠀⣰⡆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⠿⣿⣿⣿⡄⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⣠⣾⣿⣿⠟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣶⣄⠀⠀⠀⠀⠀⢀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⣻⣿⣿⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⢹⣿⡿⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⣿⠁⠈⢢⡀⠀⠀⠀⢸⡇⢀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠻⣿⡟⠒⢦⡀⠀⠀⠀
⠀⠀⣠⣤⣤⣼⡟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠸⡇⠀⠀⠀⠉⢢⣄⠀⠀⢿⠊⠳⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⣷⡄⠀⢷⠀⠀⠀
⠀⢰⠇⠀⣰⡟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⡌⣹⠗⠦⣬⣇⠀⠉⢢⡀⠀⠀⠀⠀⠀⠀⠀⠀⠘⣿⡀⢸⡄⠀⠀
⠀⡟⠀⣼⣯⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⣆⢹⡀⠀⠀⠀⠉⠁⠀⠀⢀⣀⡁⠀⠀⠉⠳⢴⡆⠀⠀⠀⠀⠀⠀⢹⣧⠈⡇⠀⠀
⠀⡇⠀⠀⢻⣦⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣾⠻⠉⠛⠂⠀⠀⠀⠀⠀⠀⠻⠿⣿⣿⣿⣶⣦⡀⠛⣇⠀⠀⠀⠀⠀⣈⣿⠀⡇⠀⠀
⢸⡇⠀⠀⢠⣿⣷⣦⣀⡸⣷⣦⣶⡂⠉⠉⠉⢁⣤⣶⡶⠀⠀⠀⣀⣀⡴⠀⠀⠀⠀⠀⠀⠈⠉⠉⠁⠀⡟⢀⣴⣟⣰⣾⣿⣏⣠⠇⠀⠀
⠈⡇⠀⠀⢸⣿⠁⠉⣿⠛⠛⠃⡇⠀⠀⢠⣶⣿⡿⠛⠁⠀⠀⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠼⢿⠟⠿⢿⡏⠀⠘⣿⡀⠀⠀⠀
⠀⢷⣀⣀⣿⠇⠀⠀⢿⡇⠀⢀⢱⡀⠀⠛⠛⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣼⠀⠀⢸⠇⠀⠀⢹⣿⣄⠀⠀
⠀⠀⣉⣿⡏⠀⠀⠀⠀⠀⠀⢸⣇⣳⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡰⣿⠃⠀⠀⠀⠀⠀⠀⣿⠈⢧⠀
⠀⠘⣿⣿⠁⠀⠀⠀⠀⠀⠀⠘⣿⡛⣶⠀⠀⣠⠔⠒⠛⠒⠦⡀⠀⠀⠀⠀⣠⡤⠶⠤⢤⣀⠀⠀⠀⢀⣏⡄⠀⠀⠀⠀⠀⡀⣿⡆⠈⣧
⣠⡾⠛⣿⣿⣧⠀⠀⠀⠀⢸⣿⠾⢿⡿⠀⣰⠃⠀⠀⠀⠀⠀⢹⡄⠀⠀⡼⠁⠀⠀⠀⠀⠈⠙⣦⠀⢸⣿⡇⣾⣣⡀⠀⢰⣿⣿⣿⣤⠾
⡟⠀⠀⠻⣿⡟⢷⡄⣤⡀⠈⣿⡀⣸⠇⠀⠏⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⡇⢀⡀⠀⠀⠀⠀⢀⡟⠀⠀⠋⣿⣿⣿⡇⣠⣿⠿⠛⢷⡀⠀
⠀⠀⠀⠀⣿⣇⣨⣿⣿⣿⣦⣽⣷⡟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠁⠀⠀⠃⠀⠙⠢⠤⠤⠴⢾⠀⠀⠀⠀⢸⣷⣿⣿⠟⠁⠀⠀⠈⣧⠀
⠀⠀⠀⠀⠈⠉⠉⠁⠈⠉⠈⢉⣿⡁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠀⠀⠀⠀⢸⡇⠀⠀⠀⠀⠀⠀⠀⣿⠀
*/


发表于 今天 00:20:17 回复(0)
这道题太简单了,直接把立体坐标(x,y,z)拆成平面坐标(x,y)(y,z)(x,z)就可以了。
可以结束了。

什么?你希望运行速度更快点?那我们再分析分析:
因为CPU管线的大敌就是“分支”,一旦预测失败就要清空管线,白费时间。
而这道题输出时几乎每个字符都有“if”,导致CPU管线效率几乎无法发挥。
有没有无分支的办法完成此题?有的。
我们观看一下最终输出,前Y行和后Z行的字符是不是本身就是个矩阵?
前Y行的Y轴朝上的,把它反向就是第几行了,再加上x坐标或z坐标就能得到字符位置了。
后Z行就更简单了,直接z坐标和x坐标就对应第几行第几列的字符位置。
这样我们就建立起了从立体坐标到缓冲区字符位置的数学关系了。
我们只需要创建缓冲区、填充、按坐标修改字符,就能一步到位得到输出了。
代码如下:
int len1 = X + Z + 2; // 前Y行的长度:X+空格+Z+换行
int len2 = X + 1; // 后Z行的长度:X+换行
byte[] buf = new byte[Y * len1 + 1 + Z * len2]; // 创建缓冲区
Arrays.fill(buf, (byte)'.'); // 全部初始化成点
for (int y = 1; y <= Y; y++) { // 前Y行的空格和换行
    buf[y * len1 - Z - 2] = ' ';
    buf[y * len1 - 1] = '\n';
}
for (int z = 0; z <= Z ; z++) { // 后Z行的换行
    buf[Y * len1 + z * len2] = '\n';
}
for (int i = 0; i < N; i++) {
    int x = in.nextInt() - 1; // x坐标正向(从左向右)
    int y = Y - in.nextInt(); // y坐标反向(从下向上)
    int z = in.nextInt() - 1; // z坐标正向(从左向右、从上向下)
    buf[y * len1 + x] = 'x'; // 主视图(第y行第x列)
    buf[y * len1 + X + 1 + z] = 'x'; // 左视图(第y行第z列)
    buf[Y * len1 + 1 + z * len2 + x] = 'x'; // 俯视图(第z行第x列)
}
System.out.write(buf); // 输出


发表于 今天 02:56:08 回复(0)

问题信息

难度:
3条回答 35浏览

热门推荐

通过挑战的用户

查看代码
三视图