棱形打印

问题

                      *                      ***                     *****                    *******                   *********                  *******                   *****                    ***                     *                      *        *        *             ***      ***      ***            *****    *****    *****           *******  *******  *******          ***************************         *******  *******  *******          *****    *****    *****           ***      ***      ***            *        *        *             *        *        *        *        *    ***      ***      ***      ***      ***   *****    *****    *****    *****    *****  *******  *******  *******  *******  *******
****************************************************  *******  *******  *******  ******* *****    *****    *****    *****    *****  ***      ***      ***      ***      ***   *        *        *        *        *    *        *        *             ***      ***      ***            *****    *****    *****           *******  *******  *******          ***************************         *******  *******  *******          *****    *****    *****           ***      ***      ***            *        *        *             *                      ***                     *****                    *******                   *********                  *******                   *****                    ***                     *             

分析

上图的棱形打印我们可以看成是一个大棱形的每个点有变成了一个个的小棱形,我们称整体的棱形为外套棱形,外套棱形的点变成的小棱形称为内嵌棱形。

之前我们打印过单个的棱形,类似于下面的:

   *     ***     *****
*******   -棱1*****  ***     *

-棱1这种的棱形打印的方法有很多,

普通棱形打法1

像初学者可能会这样做:

先打印这一行的空格 再打印这一行的*,然后一行行的打,这是最没有技术含量的的打法。

数理思维好一点的可能会采用下面的两种打印方法

普通棱形打法2

如上图 ,我们要打印一个半径为2的棱形,绿色的圆就是我们要在程序中用*代替的,我们发现所有的圆点都在四条直线上或者在四条直线的内部

所以我们得到四个判断条件,只要满足这四个条件,那么这个点在我们的程序中就是*而不是空格

n <= x + y

x + y <= 3n

x - y >= -n

x - y <= n

所以我们写出一部分代码,用来判断这个点是否是*

public static boolean isTrue(int i ,int j ,int n){int temp = Math.abs(i-j) ;//        if (( (temp) <= n ) && ( (i+j)<=(3*n) && ( n <= (i+j) )) ){   //实心棱形if (( (temp) == n ) || ( (i+j)==(3*n) || ( n == (i+j) )) ){     //空性棱形return true;}else {return false;}
}

普通棱形打法3(围点打棱)

          *            *                *
*  ==>   ***            ***              ***  *    ==>    *****            *****  ***     ==>    ******* *            *****  ***     *
棱心      1层              2层              3层
在 打法2 的基础上可以完成想上面的棱形打印顺序,不过打印起来需要3层for循环(不推荐),但是需要打印*       * *      *   *     *  *  *    *  * *  *   *  *   *  *  *  *  *  *  *
*  *  * *  *  **  *  *  *  * *  *   *  *  *  * *  *   *  *  *    *   *     * *      *
这种间隔层的棱形,就需要一层层的打。

如上图(0,0)为棱心,3为半径的一个棱形,我们会发现所有棱形内的点都满足 |x| + |y| <= 3

上面是理想状态下,下面是我们实际的控制台输出坐标模式,有时候我们的棱心坐标任意呢,依然满足上面的条件

所以我们可以写出如下代码:

//判断这个点是否是我们棱形上的点
public static boolean isOne(int i ,int j ,int x ,int y , int len){if ((Math.abs(x-i) + Math.abs(y-j) <= len)){return true;}return false;
}

本题分析

看我们本题需要打印的图形,从整体上来看,是一个大棱形;再细看大棱形都是由一个个的小棱形组成的,而且看起来小棱形就是大棱形的点,在这里,我们称大棱形叫外套棱形,小棱形叫内嵌棱形。

我们获取到外套棱形的每个点,然后对每个点实行围点打棱这样就能打印出本题的图形了。

但是我们要知道小棱形的半径和大棱形的半径,当然一个小棱形对大棱形在我们这里只能当做一个单位看

我们假设小棱形半径为:min 大棱形半径为:max

步骤

###### 1. 确认打印这个棱形需要多大的纸(数组)

需要用到多大的纸取决于我们的最大值,就是棱形的对角线长度:

小棱形最多需要 minLen=(2*min+1)

大棱形最多需要 (2*max+1)

所以我们的纸最小为 (2*min+1)(2*max+1) = maxLen

int[][] array = new int[maxLen][maxLen];
2. 在数组中标记棱形的点

我们需要先找到所有小棱形的棱形,小棱形的棱形棱心与大棱形有关,如下:

如上图:红色的棱形为外套棱形的初始状态,经过变换后,外套棱形的所有点都变为小棱形(蓝色棱形),所有的蓝色棱形组合一起就变成了我们需要的大棱形

所以我们需要先建一个简单的外套棱形,然后找到简单的外套棱形与复杂棱形之间的关系

我们发现,所有外套棱形的小棱形的棱心与简单外套棱形上的点存在以下关系

小棱形半径 minR = min

小棱形直径 minD = 2*minR +1

变换关系

( x , y ) ===>>> (x*minD + minR , y*minD+minR)

得到变换关系之后 ,我们可以通过外套棱形的半径max先构建一个简单棱形,在通过变换关系将我们的纸上的所有内嵌棱形棱心标记,最后通过围点打棱打印出问题所需要的棱形

代码

/*** @Author chen_jiapin* @Date 2023/2/13 8:45* @Version 1.0* 打印棱形  column  line*/
public class PrintPrismatic {public static void main(String[] args) {Scanner sc = new Scanner(System.in);System.out.println("请输入内嵌棱形的半径(int):");int min = sc.nextInt();System.out.println("请输入外套棱形的半径(int):");int max = sc.nextInt();int[][] array = initArr(min,max);int[][] maxArray = fun_02(max);int minD = 2*min+1;int minR = min;for (int i = 0; i < maxArray.length; i++) {for (int j = 0; j < maxArray[i].length; j++) {if (maxArray[i][j]==1){int maxX = i*minD+minR;int maxY = j*minD+minR;array[maxX][maxY]=1;fun_03(array,maxX,maxY,min);}}}print(array);}//初始化纸public static int[][] initArr(int min,int max){int minLen = min*2+1;int maxLen = (max*2+1)*minLen;int[][] array = new int[maxLen][maxLen];for (int i = 0; i < array.length; i++) {for (int j = 0; j < array[i].length; j++) {array[i][j] = 0 ;}}return array;}//打印简单棱形方法public static int[][] fun_02(int n){int m = 2*n+1;int[][] array = new int[m][m];for (int i = 0; i < array.length; i++) {for (int j = 0; j < array[i].length; j++) {array[i][j]=0;}}toWork(array,n);return array;}//标记纸上的点public static void fun_03(int[][] array,int x,int y,int len){array[x][y] = 1 ;for (int i = 0; i < array.length; i++) {for (int j = 0; j < array[i].length; j++) {if (isOne(i,j,x,y,len)){array[i][j]=1;}}}}//标记简单棱形上的点public static void toWork(int[][] array ,int n){array[n][n]=1;for (int i = 0; i < array.length; i++) {for (int j = 0; j < array[i].length; j++) {if (isOne(i,j,n,n,n)){array[i][j]=1;}}}}//判断点是否在棱形内public static boolean isOne(int i ,int j ,int x ,int y , int len){if ((Math.abs(x-i) + Math.abs(y-j) <= len)){return true;}return false;}//更具数组打印棱形public static void print(int[][] array){int line = 0;for (int i = 0; i < array.length; i++) {line++;int column = 0;for (int j = 0; j < array[i].length; j++) {column++;if (array[i][j]==1){System.out.print("*");}else System.out.print(" ");}System.out.println("\t" + column + " - " + line);}}}

控制台结果

请输入内嵌棱形的半径(int):
3
请输入外套棱形的半径(int):
4*                                  63 - 1***                               63 - 2*****                                 63 - 3*******                               63 - 4*****                                 63 - 5***                               63 - 6*                                 63 - 7*      *      *                           63 - 8***    ***    ***                         63 - 9*****  *****  *****                       63 - 10*********************                        63 - 11*****  *****  *****                          63 - 12***    ***    ***                        63 - 13*      *      *                          63 - 14*      *      *      *      *                    63 - 15***    ***    ***    ***    ***                  63 - 16*****  *****  *****  *****  *****                63 - 17***********************************                  63 - 18*****  *****  *****  *****  *****                63 - 19***    ***    ***    ***    ***                  63 - 20*      *      *      *      *                    63 - 21*      *      *      *      *      *      *              63 - 22***    ***    ***    ***    ***    ***    ***            63 - 23*****  *****  *****  *****  *****  *****  *****          63 - 24*************************************************        63 - 25*****  *****  *****  *****  *****  *****  *****          63 - 26***    ***    ***    ***    ***    ***    ***            63 - 27*      *      *      *      *      *      *              63 - 28*      *      *      *      *      *      *      *      *    63 - 29***    ***    ***    ***    ***    ***    ***    ***    ***      63 - 30*****  *****  *****  *****  *****  *****  *****  *****  *****    63 - 31
*************************************************************** 63 - 32*****  *****  *****  *****  *****  *****  *****  *****  *****    63 - 33***    ***    ***    ***    ***    ***    ***    ***    ***      63 - 34*      *      *      *      *      *      *      *      *    63 - 35*      *      *      *      *      *      *              63 - 36***    ***    ***    ***    ***    ***    ***            63 - 37*****  *****  *****  *****  *****  *****  *****          63 - 38*************************************************        63 - 39*****  *****  *****  *****  *****  *****  *****          63 - 40***    ***    ***    ***    ***    ***    ***            63 - 41*      *      *      *      *      *      *              63 - 42*      *      *      *      *                    63 - 43***    ***    ***    ***    ***                  63 - 44*****  *****  *****  *****  *****                63 - 45***********************************                  63 - 46*****  *****  *****  *****  *****                63 - 47***    ***    ***    ***    ***                  63 - 48*      *      *      *      *                    63 - 49*      *      *                          63 - 50***    ***    ***                        63 - 51*****  *****  *****                          63 - 52*********************                        63 - 53*****  *****  *****                          63 - 54***    ***    ***                        63 - 55*      *      *                          63 - 56*                                63 - 57***                                  63 - 58*****                                63 - 59*******                              63 - 60*****                                63 - 61***                                  63 - 62*                                63 - 63Process finished with exit code 0

棱形打印--进阶2(Java)相关推荐

  1. 原生js控制台(console)打印直角三角形,等腰三角形、矩形、棱形

    这是打印直角三角形的js代码 //直角三角形var num = 5;var str = "";for (var i = 0; i < num; i++) {//每一行三角形多 ...

  2. 打印棱形--进阶(Java)

    第一题 打印如下棱形,大小符号从控制台输入 * *** ***** ******* ********* ******************** ******* ***** *** * 分析:以棱形的 ...

  3. JAVA输出菱形并使用绝对值_利用for循环打印实心棱形和空心棱形

    一.要求: 提示用户输入棱形的行数,比如输入5时,打印如下实心棱形和空心棱形(由于排版问题,可能显示会有变形): * *** ***** *** * * * * *   * * * * 二.分析: A ...

  4. java使用循环打印平行四边形、三角形、棱形、空心棱形

    使用循环打印平行四边形.棱形 1.打印边长为5矩形 private static void fun1() {for(int i=0;i<5;i++){for (int j=0;j<5;j+ ...

  5. 利用for循环打印实心棱形和空心棱形

    一.要求: 提示用户输入棱形的行数,比如输入5时,打印如下实心棱形和空心棱形(由于排版问题,可能显示会有变形): * *** ***** *** * * * * *   * * * * 二.分析: A ...

  6. c语言打印空心矩形图案的程序,C语言之输出空心棱形图案

    #include #include void main() { int n,j,i; /*i为行数,j为每行中的项数*/ printf("输入图案上三角的高度n:"); scanf ...

  7. YTU 1495 蛇行矩阵 YTU 1607 字符棱形YTU 1959 图案打印YTU 2016 打印金字塔

    YTU1495: 蛇行矩阵 题目描述: Time Limit: 1 Sec  Memory Limit: 64 MB 蛇形矩阵是由1开始的自然数依次排列成的一个矩阵上三角形. Input 本题有多组数 ...

  8. 编写一个程序,使用for循环打印由 * 号构成的实心棱形和空心棱形

    题目 编写一个程序,使用for循环打印由" * " 号构成的实心棱形和空心棱形.如下图所示 思路 我们不妨假设这两个菱形是:正方形旋转45°得到的.在这个假设下去写代码,那为什么打 ...

  9. 使用for循环打印出一个棱形

    //打印一个棱形for (int i = 0;i < 11;i++){for (int j = 10;j >= i;j--){System.out.print(" ") ...

最新文章

  1. 未经任何测试的源代码开放
  2. Matlab与线性代数 -- 矩阵的重组1
  3. flex 3.0序列号
  4. 金蝶 K/3 Cloud 服务端控件编程模型
  5. Oracle清除缓存的命令,Oracle的get命令
  6. 主进程退出后子进程还会存在吗?_【干货】Linux进程模型 全解
  7. 电子病历模板_年会献礼3:浮针专家平台病历撰写系统年会启动
  8. python技术是什么意思_python中“//”表示什么意思_后端开发
  9. 前端学习(1715):前端系列javascript之页面配置
  10. 有参组装新转录本cufflinks_RNA-Seq流程(cutadapt-tophat2-cufflinks)
  11. kubernetes集群Pod详细信息为Failed create pod sandbox,缺失镜像google_containers/pause-amd64.3.0解决方法
  12. HTML5 植物大战僵尸项目介绍 和源码分析
  13. java下载https的网络图片,添加安全证书方式
  14. 小程序替换二维码logo并添加文字
  15. flutter项目运行到IOS手机
  16. RabbitMQ 入门到应用 ( 六 ) 消息可靠性
  17. 深入了解Linux内核MMU管理机制
  18. fflush函数使用
  19. 127.0.0.1 myz.php,在nginx上用FastCGI解析PHP
  20. 一个简单的画程序框图例子(画流程图)

热门文章

  1. 百度地图API,定位您的当前位置
  2. mysql 备份数据库结账_简单的结账功能(可用于各种结账)
  3. Linux磁盘扩展(非LVM+LVM)
  4. 我大抵是卷上瘾了,横竖睡不着!竟让一个Bug,搞我两次!
  5. NORDIC softDevice 蓝牙协议栈初始化程序分析(蓝牙从机,ble_peripheral)
  6. 苹果Mac在一段时间不使用后,应用(系统)会自动退出(重启)的解决方法
  7. 利用函数模板解决双倍功能
  8. python全栈需要学习什么_python全栈是什么意思
  9. D. Unusual Sequences
  10. vue写一个轮播图实例(没有自动轮播)