P1058立体图(面对代码解释)
样例:
输出样例:
(洛谷上面的那个太丑了就不放了)
乍一看好像真的没有什么思路
所以我们结合ybr大佬的代码进行分析
疑点都将在代码下面进行分析(面对代码做题模式开始)
#include<cstdio>
#include<iostream>
using namespace std;
int read(){
int ans=;
char last=' ',ch=getchar();
while(ch<''||ch>'')
last=ch,ch=getchar();
while(ch>=''&&ch<='')
{
ans=(ans<<)+(ans<<)+(ch^);
ch=getchar();
}
return last=='-'?-ans:ans;
}
char c[][],c1[][]=
{//倒着存储
"+---+",
"| |/",
"| | +",
"+---+ |",
" / /|",
" +---+",
};//6行7列 的方块
int n,m,jz[][],maxh=-,maxl=-,zbx,zby;
inline void fg(int zbx,int zby)//覆盖操作
{
for(int i=;i<=;i++)c[zbx][zby+i]=c1[][i];//这里是逐行覆盖
for(int i=;i<=;i++)c[zbx+][zby+i]=c1[][i];
for(int i=;i<=;i++)c[zbx+][zby+i]=c1[][i];
for(int i=;i<=;i++)c[zbx+][zby+i]=c1[][i];
for(int i=;i<=;i++)c[zbx+][zby+i]=c1[][i];//为什么从1开始?因为考虑到不在立方体内的空格要变成"."
for(int i=;i<=;i++)c[zbx+][zby+i]=c1[][i];//从2开始同上
}
int main()
{
m=read();n=read();
for(int i=;i<=m;i++)
{
for(int j=;j<=n;j++)
{
jz[i][j]=read();
}
}
for(int i=;i<=m;i++)//从输入的矩阵的左上角开始,满足先后,先左
for(int j=;j<=n;j++)
{
zbx=(m-i)*+;zby=(m-i)*++*(j-);//待会解释
for(int k=;k<=jz[i][j];k++,zbx+=)
{
fg(zbx,zby);
}
if(zbx+>maxh)maxh=zbx+;//我不知道为什么 (by ybr)(下面有解释)
if(zby+>maxl)maxl=zby+;
}
for(int i=maxh;i>=;i--)//上面计算zbx是默认原点是(1,1),不是(0,0)
{
for(int j=;j<=maxl;j++)
{
if(c[i][j]=='\0') printf(".");//如果c[i][j]没有被覆盖过,就输出"."
else
printf("%c",c[i][j]);
}
printf("\n");
}
return ;
}
难点:1:zbx,zby是个啥玩意?
(zbx,zby)枚举当前的这个块的左下角在输出的图中的坐标
就是枚举这个蓝点辣
注意我们把最终输出的立体图当做二维图来看
推导:
zbx:(我们先考虑只有一层的情况)
我们注意到,一个字符在上面的x轴上的贡献是1,(x轴就是上面说的x轴)
m-i:
(不要在意没有画完的最右边)
从上图看出来,m-i就是m和i隔着几“行”,其中,一“行”在x轴上的贡献是2,所以要(m-i)*2,因为一个块的边对x的贡献都是2,我们要先+2,再-2,就抵消了。
又因为下标是从1开始计算,所以要+1
每往上摞一层,zbx就要+3(一层对x轴的贡献是3)
zby:
我们拿那个蓝色的方块举例。
因为一个方块在y轴方向上的贡献是4(这里的贡献不会重复计算),所以不考虑"."的贡献,当前的zby是(j-1)*4+1
再通过肉眼观察,发现在输出图中,是"+"的那一行最左边的"."的数量都是偶数,“.”对y轴的贡献是(m-i)*2
难点2:maxh?maxl?为毛这俩的更新方法如此玄学?
ybr:我也不知道为什么
咳咳我们来研究一下这个玄学的问题
窝盟先来分析一下zby+6是个什么鬼
分析如下:
一张手动补全的图
我们看到,在第一行的方块左下角在y轴上的坐标+6就是最终输出图的最右端
zbx+2:
由于代码在执行取maxh,maxl之前有以下神奇的操作
for(int k=;k<=jz[i][j];k++,zbx+=3)
{
fg(zbx,zby);
}
这就是看每一个格子上面有几个方块
在执行完神奇的操作之后,原本表示左下角的zbx变成了左上角(可以手画一下)
由于一个在x轴上的贡献是2,所以是zbx+2
难点3:这是什么存储方法怎么好像是倒着的?
它的确是倒着的
难点4:这是什么个覆盖顺序???
从后往前枚举(i是从1到m,因为第1行在最里面),从左往右枚举,从下往上枚举
好了解释完了qwq(逃
P1058立体图(面对代码解释)的更多相关文章
- Deep Learning入门视频(下)之关于《感受神经网络》两节中的代码解释
代码1如下: #深度学习入门课程之感受神经网络(上)代码解释: import numpy as np import matplotlib.pyplot as plt #matplotlib是一个库,p ...
- [ARM] Cortex-M Startup.s启动文件相关代码解释
1. 定义一个段名为CSTACK, 这里: NOROOT表示如何定义的段没有被关联,那么同意会被优化掉,如果不想被优化掉就使用ROOT. 后面的括号里数字表示如下: (1):这个段是2的1次方即2字节 ...
- word2vec代码解释
以前看的国外的一篇文章,用代码解释word2vec训练过程,觉得写的不错,转过来了 原文链接 http://nbviewer.jupyter.org/github/dolaameng/tutorial ...
- 通过代码解释什么是API,什么是SDK?
这个问题说来惭愧,读书时找实习面的第一家公司,问的第一个问题就是这个. 当时我没能说清楚,回去之后就上百度查.结果查了很久还是看不懂,然后就把这个问题搁置了. 谁知道毕业正式工作后,又再一次地面对了这 ...
- javascript代码解释执行过程
javascript是由浏览器解释执行的脚本语言,不同于java c,需要先编译后运行,javascript 由浏览器js解释器进行解释执行,总的过程分为两大块,预编译期和执行期 下面的几个demo解 ...
- 临时2级页表的初始化过程 head_32.S 相关代码解释
page_pde_offset = (__PAGE_OFFSET >> 20); /* __PAGE_OFFSET是0xc0000000,page_pde_offset = 3072 = ...
- 零基础学python之入门和列表数据(附详细的代码解释和执行结果截图)
Python学习笔记 1 快速入门 下载安装好Python之后,在开始找到 双击打开一个窗口,这是一个shell界面编辑窗口,点击左上角的file——new file新建一个窗口,这里可以输入完整的代 ...
- java 的一个hellow word 代码解释
/* This is a simple Java program. Call this file "Example.java". */(上面是注释的方法) class Exampl ...
- TensorFlow的序列模型代码解释(RNN、LSTM)---笔记(16)
1.学习单步的RNN:RNNCell.BasicRNNCell.BasicLSTMCell.LSTMCell.GRUCell (1)RNNCell 如果要学习TensorFlow中的RNN,第一站应该 ...
随机推荐
- vue组件通信之父子组件通信
准备工作: 首先,新建一个项目,如果这里有不会的同学,可以参考我转载过的文章 http://www.cnblogs.com/Sky-Ice/p/8875958.html vue 脚手架安装及新建项目 ...
- vuer-cli 安装笔记
电脑上装 的软件全卸载了.需要 重装 .整理了一下vue-cli脚手架搭建 1 先下载git 2 再下载node 3安装淘宝镜像 (https://npm.taobao.org/) 4 安装webpa ...
- Spark-Core RDD的创建
一.RDD创建的3种方式: 1.从集合中创建RDD 2.从外部存储创建RDD 3.从其他RDD转换得到新的RDD 二.从集合中创建RDD 1.使用parallelize函数创建 scala> v ...
- 硬核!如何模拟 5w+ 的并发用户?
来自:http://t.cn/ES7KBkW 本文将从负载测试的角度,描述了做一次流畅的5万用户并发测试需要做的事情. 你可以在本文的结尾部分看到讨论的记录. 快速的步骤概要 编写你的脚本 使用JMe ...
- Appium+Python之异常自动截图
运行过程中出现异常情况,我们怎么直观的看到呢?最简单的方法就是可以把异常现象截图下来. 思路:我这里采用get_screenshot_as_file(filename)方法,filename通过获取时 ...
- C# 委托和事件 实现窗体间的通信
例子 : 点击form1上的按钮打开form2窗口,在form2窗体中的文本框中输入一个值后,在点击form2窗体中按钮,在form2中的文本框中输入的值也会在form1中的文本框中出现. form1 ...
- JDK 8 中Stream流中的去重的方法
JDK 8 中Stream流中去重的方法 1.简单的去重,可以使用distinct()方法去重,该方法是通过比较equals和hashcode值去去重, 2.复杂的去重, 例如,在一个JavaBean ...
- linux设定 runlevel 3
runlevel 查看当前系统运行级别 vi /etc/inittab //运行级别配置文件
- 线上nginx 平滑添加新模块;如(--with-http_realip_module)
nginx 添加模块1.查看当前nginx信息(配置文件路径,启动用户...) ps aux | grep nginx 2.查看当前nginx已启用的模块(记录模块信息,安装路径)./nginx -V ...
- thinkphp url和路由
一.入口模块修改 修改public下的index 加入 define('BIND_MODULE','admin'); 即可将入门模块绑定到admin模块 <?php // [ 应用入口文件 ] ...