[排版题] 例4.2 叠框

题目描述:
把一个个大小差一圈的筐叠上去,使得从上往下看时,边筐花色交错。这个工作现在要让计算机来完成,得看你的了。
输入:
是一个个的三元组,分别是,外筐尺寸n(n为满足0<n<80的奇整数),中心花色字符,外筐花色字符,后二者都为ASCII可见字符。
输出:
输出叠在一起的筐图案,中心花色与外筐花色字符从内层起交错相叠,多筐相叠时,最外筐的角总是被打磨掉。叠筐与叠筐之间应有一行间隔。
样例输入:
11 B A
5 @ W
样例输出:
  AAAAAAAAA
ABBBBBBBBBA
ABAAAAAAABA
ABABBBBBABA
ABABAAABABA
ABABABABABA
ABABAAABABA
ABABBBBBABA
ABAAAAAAABA
ABBBBBBBBBA
  AAAAAAAAA
 
   @@@
@WWW@
@W@W@
@WWW@
   @@@

解题思路: 先用一个二维数组,将内容按排版要求赋值,然后顺序输出二维数组即可。本题中,规定阵列左上角的字符坐标为(1,1),阵列右下角字符坐标为(n,n)。由中心向外进行一圈圈的排版,排每一圈时,先确定该圈的左上角(作为参照点,也可以选择其他点),然后以这个点为参照点完成该圈其他字符位置的确定。其次,每一圈的边长递增2,利用变量 i i 对当前圈的四条边进行赋值,通过判断循环次数的奇偶性,来选择对应的字符填充。最后除去四个角即可。

#include<bits/stdc++.h>
using namespace std; 

int main()
{
	int outPutBuf[82][82];//用于预排版的输出缓存 
	char a, b; // 输入的两个字符
	int n; //叠框大小 
	bool firstCase = true; // 是否为第一组数据标志,初始值为true
	while(scanf("%d %c %c", &n, &a, &b) != EOF){
		if(firstCase == true){//若是第一组数据 
			firstCase = false; // 将第一组数据标志标记成false 
		}
		else cout << endl;//否则输出换行 
		for(int i=1,j=1; i<=n; i+=2,j++){//从里至外输出每个圈
			int x = n/2+1, y=x;
			x -= j-1; y -= j-1; //计算每个圈右上角的坐标 
			char c = j%2==1 ? a:b;//计算当前圈需要使用哪个字符 
			for(int k=1; k<=i; k++){//对当前圈进行赋值 
				outPutBuf[x+k-1][y] = c; //左边赋值				 
				outPutBuf[x][y+k-1] = c; //上边赋值
				outPutBuf[x+i-1][y+k-1] = c; // 右边赋值
				outPutBuf[x+k-1][y+i-1] = c; // 下边赋值 
			} 
		}
		if(n!=1){//注意当n为1时不需此步骤 
			outPutBuf[1][1] = ' ';
			outPutBuf[n][1] = ' ';
			outPutBuf[1][n] = ' ';
			outPutBuf[n][n] = ' ';//将四角置为空格
		}
		for(int i=1; i<=n; i++){
			for(int j=1; j<=n; j++){
				printf("%c", outPutBuf[i][j]);
			}
			cout << endl;
		}
	} 
	return 0;
}

注意: 输入为1时,除去四角会导致输出为一个空格,因此,该输入单独处理。
扩展: 本题所用的先利用某二维数组进行先排版,后遍历输出的方法,适用于输出图形所具有的规律不能或者很难直接输出。

结束


猜你喜欢

转载自blog.csdn.net/zdx1996/article/details/86590268
4.2
今日推荐