本题要求你写个程序把给定的符号打印成沙漏的形状。例如给定17个“*”,要求按下列格式打印
*****
***
*
***
*****
所谓“沙漏形状”,是指每行输出奇数个符号;各行符号中心对齐;相邻两行符号数差2;符号数先从大到小顺序递减到1,再从小到大顺序递增;首尾符号数相等。
给定任意N个符号,不一定能正好组成一个沙漏。要求打印出的沙漏能用掉尽可能多的符号。
输入格式:
输入在一行给出1个正整数N(≤1000)和一个符号,中间以空格分隔。
输出格式:
首先打印出由给定符号组成的最大的沙漏形状,最后在一行中输出剩下没用掉的符号数。
输入样例:
19 *
输出样例:
*****
***
*
***
*****
2
方法:
我们首先要计算计算沙漏的层数。
通过数学知识,沙漏的各层数是成等差数列排列,每层差2个,再通过等差数列来进行计算总数。
写出一个数组,两个指针分别指向数组首尾,用指针作为判定条件,进行输出。
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,i=1;
char c;
cin >> n >> c;
while(n>2*i*i-1){ //计算沙漏层数
i++;
}
if(2*i*i-1 > n){ //判定层数是否超出
i--;
}
int cnt = i*2-1;
int sta = 0,end = cnt-1; //定义首尾指针
int a[cnt]={0};
while((sta)<=end){ //打印上半层沙漏
for(int k=0;k<cnt;k++){ //判断条件输出
if(a[k] == 0){
cout << c;
}else{
cout << ' ';
}
}
cout << endl; //数据更新
a[sta] = 1;
a[end] = 1;
sta++;
end--;
}
int b[cnt] ={0};
b[cnt/2] = 1;
int l = cnt/2,r=cnt/2; //定义首尾指针
while((r<cnt-1)&&(l>0)){ //打印下半层沙漏
l--; //数据更新
r++;
b[r] = 1;
b[l] = 1;
for(int k=0;k<cnt;k++){ //判断条件输出
if(b[k] == 1){
cout << c;
}else{
cout << ' ';
}
}
cout << endl;
}
int ans = n - (2*i*i-1);
cout << ans; //输出剩余数目
return 0;
}
测试详情:
显示的是格式错误,是因为每一行的字符后面是没有空格的。
改后代码:
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,i=1;
char c;
cin >> n >> c;
while(n>2*i*i-1){
i++;
}
if(2*i*i-1 > n){
i--;
}
int cnt = i*2-1;
int sta = 0,end = cnt-1;
int a[cnt]={0};
while((sta)<=end){
for(int k=0;k<=end;k++){
if(a[k] == 0){
cout << c;
}else{
cout << ' ';
}
}
cout << endl;
a[sta] = 1;
a[end] = 1;
sta++;
end--;
}
int b[cnt] ={0};
b[cnt/2] = 1;
int l = cnt/2,r=cnt/2;
while((r<cnt-1)&&(l>0)){
l--;
r++;
b[r] = 1;
b[l] = 1;
for(int k=0;k<=r;k++){
if(b[k] == 1){
cout << c;
}else{
cout << ' ';
}
}
cout << endl;
}
int ans = n - (2*i*i-1);
cout << ans;
return 0;
}
我们只需要把输出条件改为有边界换行就可以了。
测试情况:
总结:
我的方法比较笨,如果大家有更好的方法欢迎和大伙一起交流,讨论。
本人新手,如有问题,欢迎各位大佬指出。