题目描述]
分析:
利用程序根据输入的整数,画出由字符*
构成的该整数阶的实心菱形。给出一个示例:
n
=
7
n=7
n=7。
*
* * *
* * * * *
* * * * * * *
* * * * *
* * *
*
我们将采取拆解问题,通过四个部分的组合最终拼出这个菱形。通过观察,可以看出不管给出的整数是多少,最终形成的图形一定是一由空格
和星星*
构成个正方形(记为s)。如图1所示。
基于此我们可以先将这两条对角线画出来,是不是就成功了一半了呢?这两条对角线也很容易画,一条线是 x = 3 ( n / 2 ) x=3(n/2) x=3(n/2),另一条是 y = n / 2 y=n/2 y=n/2。给出画对角线的代码:
for (int i = 0; i < n; i ++) { // 画出十字架对角线
for (int j = 0; j < n; j ++) {
if (i == n / 2 || j == n / 2) res[i][j] = '*';
}
}
通过这一步画出的图形为:
*
*
*
* * * * * * *
*
*
*
拼出第二部分-左上角
有了这两条相交的对角线,我们只需要处理左上角需要描的点即可,然后利用相交的对角线通过关于 x x x轴对称与 y y y轴对称的方法映射到其他的三个区域!如图3所示。
那么该怎么计算左上角的该描的点呢?我们可以观察这三个点的坐标 ( 1 , 2 ) , ( 2 , 1 ) , ( 2 , 2 ) {(1,2), (2,1), (2, 2)} (1,2),(2,1),(2,2),也可以表示为 ( 1 , n / 2 − 1 ) , ( 2 , 1 ) , ( 2 , n / 2 − 1 ) {(1,n/2-1), (2,1), (2, n/2-1)} (1,n/2−1),(2,1),(2,n/2−1)。因此可以用双层循环进行遍历,伪代码如下:
// 左上角描点
for (int i = 1; i <= n / 2 - 1; i ++) { // 1到n/2-1行
for (int j = n / 2 - 1; j>= n / 2 - i; j --) { // 倒着来,从n/2-1到n/2-i列
res[i][j] = '*';
}
}
经过这一步,我们所画出来的图形为:
*
* *
* * *
* * * * * * *
*
*
*
拼出第二部分-右上角
当我们画出左上角后,可以将
n
/
2
n/2
n/2视作
y
y
y轴,进行关于y轴的对称实现映射效果。具体流程为:先遍历一遍左上角,遇到为*
的就进行映射,只需要更改列的坐标即可,给出代码:
for (int i = 1; i <= n / 2 - 1; i ++) { // 对称到右上角
for (int j = 1; j <= n / 2 - 1; j ++) {
if (res[i][j] == '*') {
res[i][n / 2 + (n / 2 - j)] = res[i][j];
}
}
}
此时生成的图形为:
*
* * *
* * * * *
* * * * * * *
*
*
*
接下来该怎么拼?
后面有多种拼法,可以先做左上角/右上角关于 x x x轴的对称,映射到左下角/右下角。这里我将上半部分当作一个整体,进行 x x x轴对称,一步到位!代码为:
for (int i = 1; i <= n - 1; i ++) { // 对称到整个下方
for (int j = 1; j <= n - 1; j ++) {
if (res[i][j] == '*') {
res[n / 2 + (n / 2 - i)][j] = res[i][j];
}
}
}
图像为:
*
* * *
* * * * *
* * * * * * *
* * * * *
* * *
*
至此,菱形就被我们画出来。这道题有需要不同的画法,上面只是笔者自己的理解,关于其他更优雅更简洁的方法请大家开动脑筋去尽情尝试吧!!
代码(Java)
import java.util.*;
public class Main {
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int x = n / 2;
char[][] res = new char[n][n];
for (int i = 0; i < n; i ++) { // 画出十字架
for (int j = 0; j < n; j ++) {
if (i == n / 2 || j == n / 2) res[i][j] = '*';
}
}
for (int i = 1; i <= n / 2 - 1; i ++) { // 左上角
for (int j = n / 2 - 1; j>= n / 2 - i; j --) {
res[i][j] = '*';
}
}
for (int i = 1; i <= n / 2 - 1; i ++) { // 对称到右上角
for (int j = 1; j <= n / 2 - 1; j ++) {
if (res[i][j] == '*') {
res[i][n / 2 + (n / 2 - j)] = res[i][j];
}
}
}
for (int i = 1; i <= n - 1; i ++) { // 对称到整个下方
for (int j = 1; j <= n - 1; j ++) {
if (res[i][j] == '*') {
res[n / 2 + (n / 2 - i)][j] = res[i][j];
}
}
}
for (int i = 0; i < n; i ++) {
for (int j = 0; j < n; j ++) {
if (res[i][j] == '*') System.out.print('*');
else System.out.print(' ');
}
System.out.println();
}
}
}