xtu oj Patchouli的金字塔

Patchouli想要绘制一个金字塔。金字塔的图案由n个正三角形和倒三角形堆叠而成,具体的绘制方法如下:

  • 每个三角形由*/\-组成,分别代表三角形的顶点和三条边。

  • 第一行只包含一个正三角形,其余各行的三角形按照”正三角形,倒三角形,正三角形,倒三角形,…… “的顺序紧致排列。

  • 除最后一行外,每一行的三角形比上一行多2个。一共输出n个三角形。

例如,n=1时,图案如下:

  *
 / \
* - *

n=2时,图案如下:

    *
   / \
  * - *
 / \
* - *

n=3时,图案如下:

    *
   / \
  * - *
 / \ /
* - *

n=7时,图案如下:

      *
     / \
    * - *
   / \ / \
  * - * - *
 / \ / \
* - * - *

Patchouli想知道n个三角形组成的金字塔的图案是怎样的?

输入

第一行包含一个正整数T(1≤T≤100),表示样例的个数。 接下来的T行,每行包含一个正整数n(1≤n≤100),表示金字塔中的三角形的个数。

输出

对于每个样例输出对应的图案。每行的行末不包含多余的空格

思路:比如输入6,应该有3层,我是先将前2层打印,因为这样有规律一下,而对于第三层,我是分情况进行分类讨论,比如第三层第一个,第三层第二个,总的来说,图形题目的核心就是分段打印!!!把有规律的先用循环打印出来,不容易用循环实现的就分类讨论 

#include <stdio.h>
#include <math.h>
void function() {
	printf("/ \\");

}
int judge(int n) {
	int ceng, k,m;
	for (ceng = 0, k = n; k > 0; ceng++, k = k - m) {
		m = 2 * ceng + 1;//如果说画两层,那么在n=2,n=3,n=4的情况下
		//2-1>0,1-5<0,但已经ceng++了,所以是两层
		//n为5的时候,k = 5,k>0,ceng = 0,m = 1,然后k =5>0,ceng++=1,k = 4;
		// m = 2*1+1=3,k = 4>0,ceng++=2,k = 4-3= 1.m  =2*2+1=5;
		//继续判断,k = 1>0,ceng++ = 3,k = 4-5= -1,m = 2*3+1=7,k<0,退出循环
		//ceng  =3,
		//原理是输入的n所在某一行的包括前面总的三角形数,依次减除开这一行的前面的总的三角形再减去下一层,根据循环的运行顺序所得到的次数就可以得到
	}
	return ceng;
}
void normalprf(int ceng) {//当前行数
	int cnt = 0;
	int hangbf = ((ceng - 1) * 2 + 1);//打印前面的
	//printf("上一层的行数%d\n", hangbf);
	for (int i = 0; i < hangbf; i++) {//开始打印前面几行的
		printf("  ");
		for (int a = hangbf - 2 - i; a >= 0; a--) {
			printf(" ");//空格输出完毕
		}//空格正常打印n-1层的,但是为了保证和n层的对齐,所以相当于每一次都在前面多输出两个空格
		cnt = i / 2;
		if (i == 0) {
			printf("*");
			}
		if ((i % 2 == 0) && i != 0) {
			printf("*");
			for (int j = 0; j < cnt; j++) {
				printf(" - *");
			}
		}
		else if ((i - 1) % 2 == 0) {
			for (int b = 0; b < (i - 1) / 2; b++) {
				printf("/ \\ ");
			}
			printf("/ \\");

		}
		printf("\n");
	}
}
//这个函数是用来打印前面的行数,但是空格一定要正常打印!!!
int main() {
	int t;
	scanf("%d", &t);
	while (t--) {
		int i, count, num;
		int n, ceng, k, m, flag = 0;
		scanf("%d", &n);
		//行数需要分析,n=1时,为3行,之后变为5行,且要输入3个数据后才能变为7行
		//之后要输入5个数据后才能变为9行
		//可以在for循环中多定义几个变量来进行行数控制
		//先不急找到i<多少,先找到画多少层数
		ceng = judge(n);//判断有多少层的函数
		int hang = 2 * ceng + 1;

		//printf("层数为%d 行数为%d\n", ceng, hang);
		while (1) {
			n--;//先将指向n的指针向左边移动,
			if (judge(n) != ceng) {//如果说n返还的层数不等于最开始的层数,说明遍历到上一层去了
				n++;//回到--前的数,
				break;//
			}
			else flag++;//说明同行某数前面有多少个数
		}
		flag++;//说明该数在同行第几个数,也就是第几个三角形
		//printf("该数据在第%d层第%d个数据\n", ceng, flag);
		//前面行数随便打印就可以了,打印满就行了
       //目前的问题打印前面几行时,虽然说是打印前面几行,但空格必须是当前的行数,也就是说空格是前面几行的下行的空格
		normalprf(ceng);//成功打印了前面一个阶段的正常情况
		//现在对输入的该三角形数量是某行的第几个数进行特殊处理
		//首先控制没有*的地方
		printf(" / \\");
		   int o=1;
		   while (1) {
			   if (o > 1) {
				   if (o % 2 == 0) {
					   printf(" /");
				   }
				   else {
					   printf(" \\");
				   }
			   }
			   o++;
			   if (o == flag + 1) {
				   break;
			   }
			  
		   }
			   printf("\n");
			   o = 1;
			   printf("* - *");
			   while (1) {
				   
				   if (o > 1) {
					   if (o % 2 == 0) {
						   printf("");
					   }
					   else {
						   printf(" - *");
					   }
				   }
				   o++;
				   if (o == flag + 1) {
					   break;
				   }
			   }
			   printf("\n");



	
	}
	
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值