牛客网BC115---超级圣诞树(java)
和女朋友坐一块的时候,突然想到了,哈哈哈哈哈
不会很难!!!
import java.util.*;
import java.lang.Math;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
/**
思考过程如下:
小三角形个数为 3^(n-1)
1 3 9 27
3^(1-1) = 1
3^(2-1) = 3
3^(3-1) = 9
3^(4-1) = 27
3^(5-1) = 81
// 去除杆子有多少层 用到了
n
3x1 3 3*2^(1-1)
3x2 6 3*2^(2-1)
3x4 12
3x8 24
3x16 48
int allP = 3 * (int)Math.pow(2, n - 1);
最底层三角形个数 没用到
n
1 1 0+1 2^(n-1)
2 2 1+1
3 4 2+1+1
4 8 4+2+1+1
5 16 8+4+2+1+1
6 32 16+8+4+2+1+1
int lastPT = Math.pow(2, n - 1)
最底层宽度 最底层三角形个数*6 用到了
n
1 6
2 12
3 24
4 48
5 96
int lastPW = (int)Math.pow(2, n - 1) * 6;
24 - 3 - 12 - 0
左边宽 最底层宽度 - 6 / 2 每三行-3 用到了
1 0
2 3-0
3 9-6-3-0
4 21-18-15-12-9-6-3-0
int leftW = (lastPW - 6) / 2;
最底层判断 需要
int nowP = 0;
int lastP = 3;
int checkN = 1;
if nowP = lastP
checkN++;
lastP += lastP
第几层,三角形大间隔 当checkN>2时,存在大间隔 最大间隔等于上一层最底层宽度-6
!!!!用到了!
int triW = 0; // 初始值
if (nowP == lastP) {
checkN++;
lastP += lastP;
if (checkN > 2) {
triW = ((int)Math.pow(2, checkN - 2) - 1) * 6; //<----用到了这个
}
starN = 2; // " * "、" * * "、"* * * "每层数量
starP = 0; // 输出了几层了
}
n
1 0
2 0
3 6-0 每三行-6
4 18-12-6-0
5 42-36-30-24-18-12-6-0
if (nowP % 3 == 0) {
triW -= 6;
leftW -= 3;
}
// " * "、" * * "、"* * * "每层
starN = 2 // " * "、" * * "、"* * * "每层数量
starP = 1 // 输出了几层了
if (starP % 4 == 0) starN *= 2;
// 星与星间距
2 2 2 3 3*1
4
4 4 4 6 3*2
4 4 4 9 3*3
10
8 8 8 12 3*4
8 8 8 15 3*5
16
16 16 16 18 3*6
16 16 16 21 3*7
22
32 32 32 24 3*8
int starW = (lastPW - starN * 6 - leftW - triW) / 2;
24 - 12 - 3 - 6
*/
/*
观察例子,可以发现,从n=2开始
左右树两边都是前者各层的形状,故直接计算好整体左边和左右两边树间距即可实现了
*/
int n = in.nextInt();
int lastPW = (int)Math.pow(2, n - 1) * 6; // 最底层宽度
int leftW = (lastPW - 6) / 2; // 左边宽 每三层-3
int allP = 3 * (int)Math.pow(2, n - 1); // 去除杆子的总层数
int checkN = 1; // 检测n,每个n对应的层数
int starW = 0; // 左右两边间距
int starP = 0; // 统计每新的开始输出几层了
String[] treeData = new String[allP + n]; // 树
for (int i = 1; i <= allP; i++) {
for (int j = 0; j < leftW; j++) System.out.print(" "); // 输出左边宽
if (i < 4) { // 相当于一个初始化的过程
String putStr = "";
if (i == 1) {
// " * "
putStr = " * ";
} else if (i == 2){
// " * * "
putStr = " * * ";
} else {
// "* * * "
putStr = "* * * ";
}
treeData[i - 1] = putStr;
System.out.print(putStr);
} else { // 开始输出前者的内容
StringBuilder putStr = new StringBuilder();
for (int j = 0; j < 2; j++) { // 左右
putStr.append(treeData[starP]);
if (j == 0) {
// 输出间距
for (int k = 0; k < starW; k++) {
putStr.append(" ");
}
}
}
System.out.print(putStr);
treeData[i - 1] = putStr.toString();
}
System.out.println();
starP++;
if (i % 3 == 0) { // 每三层,左边宽度-3,左右两边树的间距-6
leftW -= 3;
starW -= 6;
}
// 根据checkN知道当前输出是否到达每个n所处的输出范围
if ((int)Math.pow(2, checkN - 1) * 3 == i) {
checkN++;
starP = 0; // 每个n(checkN),就是新的开始
if (checkN > 2) {
starW = (int)Math.pow(2, checkN - 2) * 6 - 6; // 左右两边树的间距计算
}
}
}
// 杆子
int leftTW = (lastPW / 2) - 1;
for (int i = 0; i < n; i++) {
for (int j = 0; j < leftTW; j++) {
System.out.print(" ");
}
System.out.println("*");
}
}
}
下面附图进一步理解:

2025.1.10再看我随笔时,偶然看到这个,然后进来看了看。结合上图进行进一步思考,写了下python代码。
新思路:通过观察上图可知每新的三角形是已知输出三角形每行*2,且新的三角形与三角形之间间隔一个空格。依照此思路,可以先构造后输出最终结果。
但是仅*2 是不行的,还需要将前者的左右两边空格补齐才行。
python代码如下:
rows_data = [" * ", " * * ", "* * *"] # 初始 end_step = 5 for i in range(2, end_step + 1): empty = " " * (2 ** (i - 2)) # 之前需要补齐左右两边的空格 (2^(i-2))是规律(自行观察),3 6 12 for j in range(len(rows_data)): rows_data.append(rows_data[j] + " " + rows_data[j]) # 添加新的 rows_data[j] = empty + rows_data[j] + empty # 替换掉之前的 for i in rows_data: print(i)
哈哈哈,新思路,代码真的少QWQ
转换为java代码如下:
import java.lang.String;
import java.util.ArrayList;
import java.util.List;
public class BC142_NEW {
public static void main(String[] args) {
int triangle_num = 5; // 三角形(层)数
List<String> rows_data = new ArrayList<>();
rows_data.add(" * ");
rows_data.add(" * * ");
rows_data.add("* * *");
for (int i = 2; i < triangle_num + 1; i++) {
int data_len = rows_data.size();
for (int j = 0; j < data_len; j++) {
// 添加新数据
rows_data.add(rows_data.get(j) + " " + rows_data.get(j));
// 之前的数据加空格
StringBuilder old_data = new StringBuilder(rows_data.get(j));
int empty_num = (int)(Math.pow(2, (i - 2))); // 几个(三空格)
for (int k = 0; k < empty_num; k++) {
old_data.insert(0, " ");
old_data.append(" ");
}
rows_data.set(j, old_data.toString());
}
}
// 输出结果
for (String s : rows_data) {
System.out.println(s);
}
}
}
最后,感谢你阅读我的文章,感恩!!!

浙公网安备 33010602011771号