第四届蓝桥杯 软件类省赛真题 第八题:打印十字图

本文详细阐述了如何通过算法实现打印十字形图的过程,包括输入解析、图像生成及优化等关键步骤,提供了完整的代码实现及注释,适用于计算机科学领域的初学者。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

标题:打印十字图


    小明为某机构设计了一个十字型的徽标(并非红十字会啊),如下所示(可参见p1.jpg)



    对方同时也需要在电脑dos窗口中以字符的形式输出该标志,并能任意控制层数。
    
    为了能准确比对空白的数量,程序要求对行中的空白以句点(.)代替。


输入格式:
一个正整数 n (n<30) 表示要求打印图形的层数


输出:
对应包围层数的该标志。


例如:
用户输入:
1
程序应该输出:


再例如:
用户输入:
3
程序应该输出:



请仔细观察样例,尤其要注意句点的数量和输出位置。




资源约定:
峰值内存消耗(含虚拟机) < 64M
CPU消耗  < 1000ms




请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。


所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意:不要使用package语句。不要使用jdk1.6及以上版本的特性。
注意:主类的名字必须是:Main,否则按无效代码处理。
=======================================================
思路:
输入的数字代表外围的层数。
图形为$和.构成。我想到用递归方法。(错,哪来用递归!!)
首个:当输入1时,按以上规格输出,方法限制变量n来变化圈数
第二个:对比第一个,发现相同的在于竖直为..+n个$+..,水平也是,这让我想到了输出杨辉三角那道题
新建一个数组(长度为输入而定),然后把固定的图案存进去。
长度规律,输入1时长宽为9
 输入2时长宽为13
 输入3时长宽为17(每次加上4)

确定外围的图像后,内围合外围有什么关系??,我把其他的删除,观察对比。
删除后:   发现如果牵强说外围内围关系不太简单,干脆重绘内围,称为B围(外围为A围)

虽然外围内围关系不大,不过却不难发现A围和里面包含的外围很相近。B围则相似于内围。这地方可调用函数。

(仅是四个角不同而已)

(B层一模一样)

现在整理一下获取的信息:首先,
长度规律,输入1时长宽为9
 输入2时长宽为13
 输入3时长宽为17(每次加上4)
外围之间仅角不同(最外面的是点)
内围之间一模一样

代码实录:
1.获取用户输入数字n
2.新建一个二维数组,长宽为 kuan=(5+n*4)
3.给[i=1][j]赋个$,并且[i=1][2]和[i=1][kuan-2]赋为.
给[i][j=1]赋个$,并且[i=2][j=1]和[i=kuan-2][j=1]赋为.
给[i=kuan][j]赋个$,[i=kuan][2]和[i=kuan][kuan-2]赋为.
给[i][j=kuan]赋个$,并且[i=2][j=kuan]和[i=kuan-2][j=kuan]赋为.
(发现规律,以上可以用一个方法解决)
4.给[i=2][j]赋个.,并且[i=2][j=3]赋值$,[i=2][j=kuan-2]
写到这里发现问题,新的代码会将旧的代码覆盖,所以选择从里面到外面或许比从外面到里面好。
先找中间打印和宽的关系:
现在先完成一个分解任务:打印中间一圈的情况,根据圈数的变多,中间图案进行正确移动。
1.获取用户输入数字n
2.新建一个二维数组,长宽为 kuan=(5+n*4)
3.打印最小个
4.for(n=1;1<=n-1;n++):将二维数组往下右移动2位
补上外围的图案:补上相对位置的空格:

代码1:此代码实现了创建数组并且打印初级图像

错误代码尝试:

package com.aiqiongdiao;
import java.util.Scanner;


public class Test {
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
int n= input.nextInt();
final int N=5+4*n+1;
mix(N);
}


public static void mix(int N){    //打印最初图像
char tu[][] = new char[N][N];
for(int i=1;i<=9;i++){
if(i%2!=0){
for(int j=1;j<=9;j++){
tu[i][j]='$';
}
}
else{
for(int j=1;j<=9;j++){
tu[i][j]='.';
}
}
}
tu[1][1]=tu[1][2]=tu[1][8]=tu[1][9]=
tu[3][4]=tu[3][6]=tu[5][2]=tu[5][8]=
tu[7][4]=tu[7][6]=tu[9][1]=tu[9][2]=tu[9][8]=tu[9][9]='.';
for(int j=1;j<=9;j++){
for(int i=1;i<=9;i++){
System.out.print(tu[i][j]);
}
System.out.println();
}
}


public static void dayin(int m){
}
}

第二步,现在将整个图像进行位置正确化!
代码尝试(错误):
package com.aiqiongdiao;
import java.util.Scanner;


public class Test {
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
int n= input.nextInt();
final int N=5+4*n+1;   //数组量
final int Y=(n-1)*2;
char tu[][] = new char[N][N];
mix(N,tu);   //打印初图案,传递数组的方法
weizhi(Y,tu,N);
}


public static void mix(int N,char tu[][]){    //打印最初图像,数组接收需要[][]
for(int i=1;i<=9;i++){
if(i%2!=0){
for(int j=1;j<=9;j++){
tu[i][j]='$';
}
}
else{
for(int j=1;j<=9;j++){
tu[i][j]='.';
}
}
}
tu[1][1]=tu[1][2]=tu[1][8]=tu[1][9]=
tu[3][4]=tu[3][6]=tu[5][2]=tu[5][8]=
tu[7][4]=tu[7][6]=tu[9][1]=tu[9][2]=tu[9][8]=tu[9][9]='.';
tu[2][3]=tu[2][7]=tu[4][1]=tu[4][5]=tu[4][9]=tu[6][1]=
tu[6][5]=tu[6][9]=tu[8][3]=tu[8][7]='$';
for(int j=1;j<=9;j++){
for(int i=1;i<=9;i++){
System.out.print(tu[i][j]);
}
System.out.println();
}
}


public static void weizhi(int Y,char tu[][],int N){  //位置变化
for(int j=9;j>0;j--){   //从大到小,后面的才不会被覆盖
for(int i=9;i>0;i--){
tu[i+2][j+2]=tu[i][j];
}
}
for(int j=(N-1);j>0;j--){   //从大到小,后面的才不会被覆盖
for(int i=(N-1);i>0;i--){
System.out.print(tu[i][j]);
}
System.out.println();
}
}


public static void dayin(int m){

}
}

============================================
进行新的尝试:
1.获取圈数N,计算出圈数和长宽的关系:kuan=(5+n*4)
2.所有的数组赋值.
3.最外面的一圈打印
4.将特例化为变量的常例,按数量打印
5.打印中心


做这种题:
1.将图像转化为规则图像
2.根据你会怎么去画的方式赋点

为什么打印的图像总是这样子??
1
$$$$$$$$
$.......
$.......
$.......
$.......
$.......
$.......
$.......


原来是我输出打印的时候长度弄成了length-1...汗(-__-)b)

经过思考后终于做成了。


代码实现:
package com.aiqiongdiao;
import java.util.Scanner;


public class Main {    
	/***
	 * 粗糙图像赋值
	 */
	public static void fuzhi(String arr[][],int kuan,int zhongjian){
		int bianchang=kuan;
		//设立对比点
		int x=0;  //左上角
		int y=0;
		int x1=kuan-1;   //右下角
		int y1=kuan-1;
		while(true){
			if(bianchang==5){
				break;
			}
			daquan(arr,x,y,x1,y1,bianchang);//打圈
			x=x+2;
			y=y+2;
			x1=x1-2;
			y1=y1-2;
			bianchang=bianchang-4;
		}
		//打印中心
		for(int i=0;i<5;i++){
			arr[zhongjian][zhongjian-2+i]="$";
			arr[zhongjian-2+i][zhongjian]="$";
		}
	}
	/**
	 * 赋值外圈
	 */
	public static void daquan(String arr[][],int x,int y,int x1,int y1,int kuan){
//一三边赋值
		int a=x;  //小心数值变化对下面赋值的影响
		int a1=x1;
		for(int i=0;i<kuan;i++){
			arr[y][a]="$";
			a++;
			arr[y1][a1]="$";
			a1--;
		}	
//四二边赋值
		for(int i=0;i<kuan;i++){
			arr[y][x]="$";  //没有下一个,不用怕影响到
			y++;
			arr[y1][x1]="$";
			y1--;    //注意是减减
		}
	}
	/**
	 * 细修图像
	 */
	public static void xixiu(String arr[][],int zhongjian,int kuan){
		int x=0;   //定义小正方向左上角的坐标
		int x1=kuan-1;
		while(true){
			if(x>zhongjian-4){break;}
			xiaozheng(arr,x,x);    //在小正方形中处理
			xiaozheng2(arr,x1,x);  //第二个角
			xiaozheng3(arr,x1,x1);   //第三个角
			xiaozheng4(arr,x,x1);   //第四个角
			x1=x1-2;
			x=x+2;
		}
		//去掉最外面的四个点
		qudian(arr,kuan);
	}
	/**
	 * 小正方形的处理
	 */
	//小正1
	public static void xiaozheng(String  arr[][],int x,int y){
		arr[y][x+1]=".";    //减两个
		arr[y+1][x]=".";    
		arr[y+2][x+1]="$";  //加三个
		arr[y+2][x+2]="$";
		arr[y+1][x+2]="$";
	}
	//小正2
	public static void xiaozheng2(String  arr[][],int x,int y){
		arr[y][x-1]=".";    //减两个
		arr[y+1][x]=".";    
		arr[y+2][x-1]="$";  //加三个
		arr[y+2][x-2]="$";
		arr[y+1][x-2]="$";
	}
	//小正3
	public static void xiaozheng3(String  arr[][],int x,int y){
		arr[y][x-1]=".";    //减两个
		arr[y-1][x]=".";    
		arr[y-2][x-1]="$";  //加三个
		arr[y-2][x-2]="$";
		arr[y-1][x-2]="$";
	}
	//小正4
	public static void xiaozheng4(String  arr[][],int x,int y){
		arr[y][x+1]=".";    //减两个
		arr[y-1][x]=".";    
		arr[y-2][x+1]="$";  //加三个
		arr[y-2][x+2]="$";
		arr[y-1][x+2]="$";
	}
	public static void qudian(String arr[][],int kuan){
		arr[0][0]=".";
		arr[0][kuan-1]=".";
		arr[kuan-1][kuan-1]=".";
		arr[kuan-1][0]=".";
	}
	
	/**
	 * 打印图像
	 * @param arr
	 */
	public static void print(String arr[][]){
		for(int i=0;i<arr.length;i++){
			for(int j=0;j<arr.length;j++){
				System.out.print(arr[i][j]);
			}
			System.out.println();
		}
	}
		
	
	public static void main(String[] args) {
//		1.获取圈数N
		Scanner input = new Scanner(System.in);
		int a=input.nextInt();		
//		计算出圈数和长宽的关系:kuan=(5+n*4)
		int kuan=5+a*4;
//		2.新建数组
		String arr[][]=new String[kuan][kuan];
//		3.打印背景
		for(int i=0;i<arr.length;i++){
			for(int j=0;j<arr.length;j++){
				arr[i][j]=".";
			}
		}
//		4.粗糙图赋值	
		int zhongjian=(kuan-1)/2;
		fuzhi(arr,kuan,zhongjian);
//		5.细修图像
		xixiu(arr,zhongjian,kuan);
//		5.打印图像
		print(arr);
		
//		4.将特例化为变量的常例,按数量打印


	}
}





注意:对于打印图像题,我想到了这样一种解题模板。
1.获取用户数据
2.新建数组,填充背景
3.调用大概打印图像函数(对于简单图像可直接跳过)
4.调用细修函数(细修可以把图像分割成小图像来看,就像上面的正方形)
5.调用打印函数




  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值