PAT (Basic Level) Practice 1027 打印沙漏
1.题目描述
2.思路及代码
注意事项
①每一行末尾不能有空格
②剩余符号数为0时也要输出
③每一行字符数为奇数
思路:
先计算第一行符号数量:设第一行符号数为k,根据等差数列求和公式可以求出半个沙漏的字符数,再乘上2减去1就等于整个沙漏的字符数量。
从而反解出最大奇数k值:
计算出第一行字符数k后,每一行字符数先以2为差递减至1,再递增。
并且沙漏总行数就等于第一行字符数。
代码:
import java.io.*;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws IOException{
//BufferedReader bR = new BufferedReader(new InputStreamReader(System.in));
Scanner sc = new Scanner(System.in);
//读入数据
String[] strs = sc.nextLine().split(" ");
sc.close();
//总数量
int n = Integer.parseInt(strs[0]);
//字符
char c = strs[1].charAt(0);
//计算第一行打印符号的数量
//设k为第一行字符数,等差数列求和等于n,反解出k
int k =(int) ( Math.sqrt(2 * (n + 1)) - 1 );
//保证k为奇数
if(k % 2 == 0)
k--;
//计算剩余符号数
int rest = n - (k+1) * (k+1) / 2 + 1;
//控制符号数量先递减后递增
int sign = -1;
//row控制打印字符的行数;观察发现:沙漏的总行数恰等于第一行字符数k
//i记录当前行的字符数,初始为k。先递减至1,再递增
int i, j, row, l;
for(row = 0, i = k; row < k; row++) {
l = (k - i) / 2; //当前行的空格数
for(j = 0; j < l; j++) //先打印空格
System.out.print(" ");
for(j = 0; j < i; j++) //再打印字符
System.out.print(c);
System.out.println(); //换行
i += sign * 2; //控制增减
if(i == 1) //递减至1后开始递增
sign = 1;
}
//打印剩余数量
System.out.print(rest);
}
}