1027 打印沙漏(C语言详解)

前言

这个题目思路不是很复杂但是我也写了好久(技术菜),关键在于编写“漏斗”的时候的技巧,左边留空格右边不用留就行了。
比较让我疑惑的是为什么构不成沙漏也要打印出一个符号*不然有测试点通不过。

正文

题目

本题要求你写个程序把给定的符号打印成沙漏的形状。例如给定17个“*”,要求按下列格式打印

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

所谓“沙漏形状”,是指每行输出奇数个符号;各行符号中心对齐;相邻两行符号数差2;符号数先从大到小顺序递减到1,再从小到大顺序递增;首尾符号数相等。

给定任意N个符号,不一定能正好组成一个沙漏。要求打印出的沙漏能用掉尽可能多的符号。

输入格式:

输入在一行给出1个正整数N(≤1000)和一个符号,中间以空格分隔。

输出格式:

首先打印出由给定符号组成的最大的沙漏形状,最后在一行中输出剩下没用掉的符号数。

输入样例:
19 *
输出样例:
*****
 ***
  *
 ***
*****
2

假设count为最长一排星星个数;
打印空格规律
上半部分:空格数 k=行数-1
下半部分:空格数 k=count-行数

*****   1
 ***    2   上半部分
  *     3
--------
 ***    4
*****   5   下半部分

代码:

#include <stdio.h>
int print(int count,char c);
int main(){
	int num,sum=0;
	int i,flag,count,k;
	char c;
	scanf("%d %c",&num,&c);
	/* 当输入的数大于等于7时*/
    if(num>=7){
	for(i=3;sum<=num;i+=2){//保证打印的*小于输入的数
    	flag=i;//可以容纳第一行的*个数 
		count=i;
		sum=0;
    	while(count>0){
    		sum=sum+count;
    		count-=2;
		}
		sum=2*sum-1;//*个数
	}
     print(flag-2,c);//打印漏斗,要减去2
	 k=num-sum+flag*2;//剩余的*个数
	 printf("%d",k);
}
	/* 当输入的数小于7*/
   else{
		printf("%c\n",c);//要打印出一颗星星,不然会报错
        printf("%d",num-1);
	}
} 
/*打印漏斗*/
int print(int count,char c){//count 为第一排的个数,c 为输出的字符
	int i=0;
	int j=0 ;
	int k,count;
	/*上半部分  */
	for(j=0;j<(count+1)/2;j++){
		k=j;//用于储存左边空格的数量
		for(i=0;i<count-j;i++){//算上空格‘ ’每次比上一行少输出1个用count-j
			if(k){   
				   printf(" ");//先打印左边的空格
				   k--;  	
			}
			else
				printf("%c",c);//再打印字符*
		}  
		putchar('\n');
	}
	/*下半部分  */
	for(j;j<count;j++){//打印剩余
		  k=count-j-1;//空格数量,因为上半部分j从0开始 所以再-1
		for(i=0;i<j+1;i++){
			if(k){
			    printf(" ");
				k--;
			}
			else
			    printf("%c",c);
		}
		if(j<count)//最后一行不用打印\n
		  putchar('\n');
	}
} 

最后,来来来,膜拜一下大佬的代码:

#include <stdio.h>
void print(char ch, int count) {
	while (count-- > 0)putchar(ch);
}	//print(ch,c):打印ch字符c遍。
void printLine(char ch, int j, int width) {
	print(' ', j);	//j为空格数量
	print(ch, width - 2*j);	//width一行总宽度  - 两侧的空格数量2j
	putchar('\n');	//换行(右侧的空格不需要也不允许真正地输出)
}	//打印沙漏专用,ch为待打印字符,h为上三角层数
int main(){
	int n, n0 = 1;	//n ch即为题目输入。n0是沙漏实际打印字符个数
	char ch;	//样例中ch=='*'
	int h = 1;	//沙漏上三角层数
	scanf("%d %c", &n, &ch);
	while (1){	//迭代法试出
		int temp = n0 + 2 * (2 * h + 1);	//新增加首末两行的ch数量
		if (temp <= n) {		//没有超出n
			n0 = temp;	h++;
		}else break;	//否则超出则跳出
	}
	int j, row = 2 * h - 1;	//j为空格数量,row为总行数==首末行ch数量
	for (j = 0; j<h; j++) {		//打印上半部分(含中间)
		printLine(ch, j, row);
	}
	for (j = h-2; j >= 0; j--){	//打印下半部分(不含中间)
		printLine(ch, j, row);
	}
	printf("%d", n - n0);
	return 0;
}

还有更简单的:我什么时候才能写出这样的代码555
https://blog.csdn.net/q839219286/article/details/90513915

  • 21
    点赞
  • 78
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值