蓝桥杯解题(一)打印十字图 时间限制:1.0s 内存限制:256.0MB

原题描述:
历届试题 打印十字图  
时间限制:1.0s   内存限制:256.0MB

 

锦囊1
使用二维数组。
锦囊2
使用二维数组把图形保存下来,然后再输出。
问题描述

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

20180309145513502

对方同时也需要在电脑dos窗口中以字符的形式输出该标志,并能任意控制层数。

输入格式
一个正整数 n (n<30) 表示要求打印图形的层数。
输出格式
对应包围层数的该标志。
样例输入1
1
样例输出1
20180309154805882
样例输入2
3
样例输出2
20180309154844865
提示
请仔细观察样例,尤其要注意句点的数量和输出位置。
解题思路:

1、观察规律:发现中心十字始终处于中心点,没次增加外层包围都会使得用于存储数据的二维数组的两个维度成为相同的奇数值。所以中心点容易确定。

2、具有初始状态,当层数为0时,中心十字任然存在,且有包围层数正整数n,0<n<30;

3、选择一个维度观察发现除去初始状态外,包围层只能是与边界点不同的符号表示,且全局结果仅呈现两种符号

所以尝试使用类似于小游戏中地图绘制的方式生成该图案,从中心点出发将全部图形分为四个区域单独绘制(因为中心有初始状态,可以作为某种规则的初始输入参数)。

4、实现过程中注意内存管理,因为我在第一次编写该代码中因疏忽,出现内存泄露问题,使得内存占用巨大。20180309140012935

代码如下(并没有对高度重用部分进行细化封装,感兴趣的可以自行封装,加深代码理解):

#include <iostream> 
using namespace std;

class Point
{
	public:
	int m_x_i;
	int m_y_i;
	
	Point(int x,int y):m_x_i(x),m_y_i(y){}
	~Point(){}
	
	void deletePoint(Point* p)
	{
		if (p!= NULL)
		delete p;
		p=NULL;
	}
	
	int getX(){return this->m_x_i;}
	int getY(){return this->m_y_i;}
	
	void setX(int x){m_x_i= x;}
	void setY(int y){m_y_i= y;}
	
	//获取周围8个点 
	Point* getLeftPoint(const Point& pt){Point* rpt= new Point(pt.m_x_i, pt.m_y_i-1); return rpt;}		// 获取左边的点 
	Point* getRightPoint(const Point& pt){Point* rpt= new Point(pt.m_x_i, pt.m_y_i+1); return rpt;}		// 获取右边的点
	Point* getUppPoint(const Point& pt){Point* rpt= new Point(pt.m_x_i-1, pt.m_y_i); return rpt;}		// 获取上边的点 
	Point* getDownPoint(const Point& pt){Point* rpt= new Point(pt.m_x_i+1, pt.m_y_i); return rpt;}		// 获取下边的点 
	
	Point* getLeft_UppPoint(const Point& pt){Point* rpt= new Point(pt.m_x_i-1, pt.m_y_i-1); return rpt;}		// 获取左上边的点 
	Point* getRight_UppPoint(const Point& pt){Point* rpt= new Point(pt.m_x_i-1, pt.m_y_i+1); return rpt;}		// 获取右上边的点 
	Point* getLeft_DownPoint(const Point& pt){Point* rpt= new Point(pt.m_x_i+1, pt.m_y_i-1); return rpt;}		// 获取左下边的点 
	Point* getRight_DownPoint(const Point& pt){Point* rpt= new Point(pt.m_x_i+1, pt.m_y_i+1); return rpt;}		// 获取右下边的点 

};
class PrintGraphics
{
	public:
	int** m_map_ipp;
	int m_level_i;
	
	PrintGraphics(int n);		// 自定义构造函数 
 	~PrintGraphics(){ delete []m_map_ipp;} 		// 析构函数
	 
	void mapInit(void); 		// 地图初始化 
 	void asRuleSet(void);		// 依据规则设置地图 
 	void printMap(void);		// 打印最终地图 
};
PrintGraphics::PrintGraphics(int n):m_level_i(4*n+5)		// 自定义构造函数 
	{
		//分配存储空间 
		m_map_ipp= new int*[4*n+5];
		for( int i=0; i<(4*n+5); i++ )
 		{
      		m_map_ipp[i] = new int [4*n+5]  ;
  		}
  		//执行初始化 
  		this->mapInit();
  		//执行按规则铺地图 
  		this->asRuleSet();
 	}

void PrintGraphics:: mapInit(void)
 	{
 		// 预初始化
 		for(int i=0;i<m_level_i;++i)		
 		{
 			for(int j=0;j<m_level_i;++j)
 				m_map_ipp[i][j]=-1;
 		}
 		//初始化四个边角
 		m_map_ipp[0][0]=m_map_ipp[m_level_i-1][0]=m_map_ipp[0][m_level_i-1]=m_map_ipp[m_level_i-1][m_level_i-1]= '.';	
		//初始化中心十字架	
		for(int i=(m_level_i-5)/2;i<(m_level_i/2)+3;++i)
			m_map_ipp[i][m_level_i/2]='$';
		for(int i=(m_level_i-5)/2;i<(m_level_i/2)+3;++i)
			m_map_ipp[m_level_i/2][i]='$';
 		
 	}
 	
void PrintGraphics:: asRuleSet(void)
	 {
	 	int markFoot= 0;		// 标记行走步长 
	 	Point* markStartPoint= new Point(m_level_i/2,m_level_i/2);	//初始化设置为十字中心 ,起始点标记 
		Point* startPoint=new Point(markStartPoint->getX(),markStartPoint->getY()); //设置起始点 
		
		Point* PointContainer= NULL;  //点容器,用于解决内存泄露问题 
	 	//左上区域设置
	 	do{
	 		//如果当前点的左边未被设置 
	 		PointContainer= startPoint->getLeftPoint(*startPoint);	//将要查询的点放入容器中 
	 		if(m_map_ipp[PointContainer->getX()][PointContainer->getY()] == -1)	
	 		{
	 			if(m_map_ipp[startPoint->getX()][startPoint->getY()] == '$') // 如果当前点为 $ ,设置成 . 
	 				m_map_ipp[PointContainer->getX()][PointContainer->getY()] = '.';
	 			if(m_map_ipp[startPoint->getX()][startPoint->getY()] == '.') // 如果当前点为 . ,设置成 $ 
	 				m_map_ipp[PointContainer->getX()][PointContainer->getY()] = '$';	
	 		}
	 		//释放内存
	 		if(PointContainer != NULL)
	 			PointContainer->deletePoint(PointContainer);
	 		
	 		//如果当前点的左上边未被设置 
	 		PointContainer= startPoint->getLeft_UppPoint(*startPoint);	//将要查询的点放入容器中 
	 		if(m_map_ipp[PointContainer->getX()][PointContainer->getY()] == -1)	
	 		{
	 			if(m_map_ipp[startPoint->getX()][startPoint->getY()] == '$') // 如果当前点为 $ ,设置成 . 
	 				m_map_ipp[PointContainer->getX()][PointContainer->getY()] = '.';
	 			if(m_map_ipp[startPoint->getX()][startPoint->getY()] == '.') // 如果当前点为 . ,设置成 $ 
	 				m_map_ipp[PointContainer->getX()][PointContainer->getY()] = '$';
	 		}
	 		//释放内存
	 		if(PointContainer != NULL)
	 			PointContainer->deletePoint(PointContainer);
	 		//如果当前点的上边未被设置 
	 		PointContainer= startPoint->getUppPoint(*startPoint);	//将要查询的点放入容器中 
	 		if(m_map_ipp[PointContainer->getX()][PointContainer->getY()] == -1)	
	 		{
	 			if(m_map_ipp[startPoint->getX()][startPoint->getY()] == '$') // 如果当前点为 $ ,设置成 . 
	 				m_map_ipp[PointContainer->getX()][PointContainer->getY()] = '.';
	 			if(m_map_ipp[startPoint->getX()][startPoint->getY()] == '.') // 如果当前点为 . ,设置成 $ 
	 				m_map_ipp[PointContainer->getX()][PointContainer->getY()] = '$';
	 		}
	 		//释放内存
	 		if(PointContainer != NULL)
	 			PointContainer->deletePoint(PointContainer);
	 		//进入上一行
		 	if(startPoint->getX() != 1 && startPoint->getY() == 1 && markFoot <= m_level_i/2 -2)
		 	{
		 		markFoot+=1;
		 		startPoint->setX(markStartPoint->getX()-markFoot);
		 		startPoint->setY(markStartPoint->getY());
		 	}
		 	else
		 		//没有到达最左,向左走;
		 		startPoint->setY(startPoint->getY()-1); 
		 		
	 	}while(startPoint->getX() != 0 &&startPoint->getY()!= 0); 
	
	 	markFoot = 0;		//重置 
	 	startPoint->setX(markStartPoint->getX());
	 	startPoint->setY(markStartPoint->getY());
		//右上区域设置
	 	do{
	 		//如果当前点的上边未被设置 
	 		PointContainer= startPoint->getUppPoint(*startPoint);	//将要查询的点放入容器中 
	 		if(m_map_ipp[PointContainer->getX()][PointContainer->getY()] == -1)	
	 		{
	 			if(m_map_ipp[startPoint->getX()][startPoint->getY()] == '$') // 如果当前点为 $ ,设置成 . 
	 				m_map_ipp[PointContainer->getX()][PointContainer->getY()] = '.';
	 			if(m_map_ipp[startPoint->getX()][startPoint->getY()] == '.') // 如果当前点为 . ,设置成 $ 
	 				m_map_ipp[PointContainer->getX()][PointContainer->getY()] = '$';
	 		}
	 		//释放内存
	 		if(PointContainer != NULL)
	 			PointContainer->deletePoint(PointContainer);
	 		//如果当前点的右上边未被设置 
	 		PointContainer= startPoint->getRight_UppPoint(*startPoint);	//将要查询的点放入容器中 
	 		if(m_map_ipp[PointContainer->getX()][PointContainer->getY()] == -1)	
	 		{
	 			if(m_map_ipp[startPoint->getX()][startPoint->getY()] == '$') // 如果当前点为 $ ,设置成 . 
	 				m_map_ipp[PointContainer->getX()][PointContainer->getY()] = '.';
	 			if(m_map_ipp[startPoint->getX()][startPoint->getY()] == '.') // 如果当前点为 . ,设置成 $ 
	 				m_map_ipp[PointContainer->getX()][PointContainer->getY()] = '$';
	 		}
	 		//释放内存
	 		if(PointContainer != NULL)
	 			PointContainer->deletePoint(PointContainer);
	 		//如果当前点的右边未被设置 
	 		PointContainer= startPoint->getRightPoint(*startPoint);	//将要查询的点放入容器中 
	 		if(m_map_ipp[PointContainer->getX()][PointContainer->getY()] == -1)	
	 		{
	 			if(m_map_ipp[startPoint->getX()][startPoint->getY()] == '$') // 如果当前点为 $ ,设置成 . 
	 				m_map_ipp[PointContainer->getX()][PointContainer->getY()] = '.';
	 			if(m_map_ipp[startPoint->getX()][startPoint->getY()] == '.') // 如果当前点为 . ,设置成 $ 
	 				m_map_ipp[PointContainer->getX()][PointContainer->getY()] = '$';
	 		}
	 		//释放内存
	 		if(PointContainer != NULL)
	 			PointContainer->deletePoint(PointContainer);
	 		//进入上一行
		 	if(startPoint->getX() != 1 && startPoint->getY() == markStartPoint->getX()*2-1 && markFoot <= m_level_i/2 -2)
		 	{
		 		markFoot+=1;
		 		startPoint->setX(markStartPoint->getX()-markFoot);
		 		startPoint->setY(markStartPoint->getY());
		 	}
		 	else
		 		//没有到达最右,向右走;
		 		startPoint->setY(startPoint->getY()+1); 
		}while(startPoint->getX() != 0 &&startPoint->getY()!= markStartPoint->getX()*2); 

		markFoot = 0;		//重置 
	 	startPoint->setX(markStartPoint->getX());
	 	startPoint->setY(markStartPoint->getY());
		//右下区域设置
		 do{
	 	
	 		//如果当前点的右边未被设置 
	 		PointContainer= startPoint->getRightPoint(*startPoint);	//将要查询的点放入容器中 
	 		if(m_map_ipp[PointContainer->getX()][PointContainer->getY()] == -1)	
	 		{
	 			if(m_map_ipp[startPoint->getX()][startPoint->getY()] == '$') // 如果当前点为 $ ,设置成 . 
	 				m_map_ipp[PointContainer->getX()][PointContainer->getY()] = '.';
	 			if(m_map_ipp[startPoint->getX()][startPoint->getY()] == '.') // 如果当前点为 . ,设置成 $ 
	 				m_map_ipp[PointContainer->getX()][PointContainer->getY()] = '$';
	 		}
	 		//释放内存
	 		if(PointContainer != NULL)
	 			PointContainer->deletePoint(PointContainer);
	 		//如果当前点的右下边未被设置 
	 		PointContainer= startPoint->getRight_DownPoint(*startPoint);	//将要查询的点放入容器中 
	 		if(m_map_ipp[PointContainer->getX()][PointContainer->getY()] == -1)	
	 		{
	 			if(m_map_ipp[startPoint->getX()][startPoint->getY()] == '$') // 如果当前点为 $ ,设置成 . 
	 				m_map_ipp[PointContainer->getX()][PointContainer->getY()] = '.';
	 			if(m_map_ipp[startPoint->getX()][startPoint->getY()] == '.') // 如果当前点为 . ,设置成 $ 
	 				m_map_ipp[PointContainer->getX()][PointContainer->getY()] = '$';
	 		}
	 		//释放内存
	 		if(PointContainer != NULL)
	 			PointContainer->deletePoint(PointContainer);
	 		//如果当前点的下边未被设置 
	 		PointContainer= startPoint->getDownPoint(*startPoint);	//将要查询的点放入容器中 
	 		if(m_map_ipp[PointContainer->getX()][PointContainer->getY()] == -1)	
	 		{
	 			if(m_map_ipp[startPoint->getX()][startPoint->getY()] == '$') // 如果当前点为 $ ,设置成 . 
	 				m_map_ipp[PointContainer->getX()][PointContainer->getY()] = '.';
	 			if(m_map_ipp[startPoint->getX()][startPoint->getY()] == '.') // 如果当前点为 . ,设置成 $ 
	 				m_map_ipp[PointContainer->getX()][PointContainer->getY()] = '$';
	 		}
	 		//释放内存
	 		if(PointContainer != NULL)
	 			PointContainer->deletePoint(PointContainer);
	 		//进入下一行
		 	if(startPoint->getX() != markStartPoint->getX()*2-1 && startPoint->getY() == markStartPoint->getX()*2-1 && markFoot <= m_level_i/2 -2)
		 	{
		 		markFoot+=1;
		 		startPoint->setX(markStartPoint->getX()+markFoot);
		 		startPoint->setY(markStartPoint->getY());
		 	}
		 	else
		 		//没有到达最右,向右走;
		 		startPoint->setY(startPoint->getY()+1); 
	 	}while(startPoint->getX() != 0 &&startPoint->getY()!= markStartPoint->getX()*2); 
	
	 	//左下区域设置
	 	markFoot = 0;		//重置 
	 	startPoint->setX(markStartPoint->getX());
	 	startPoint->setY(markStartPoint->getY());	
	 	do{
	 		//如果当前点的左边未被设置 
	 		PointContainer= startPoint->getLeftPoint(*startPoint);	//将要查询的点放入容器中 
	 		if(m_map_ipp[PointContainer->getX()][PointContainer->getY()] == -1)	
	 		{
	 			if(m_map_ipp[startPoint->getX()][startPoint->getY()] == '$') // 如果当前点为 $ ,设置成 . 
	 				m_map_ipp[PointContainer->getX()][PointContainer->getY()] = '.';
	 			if(m_map_ipp[startPoint->getX()][startPoint->getY()] == '.') // 如果当前点为 . ,设置成 $ 
	 				m_map_ipp[PointContainer->getX()][PointContainer->getY()] = '$';
	 		}
	 		//释放内存
	 		if(PointContainer != NULL)
	 			PointContainer->deletePoint(PointContainer);
	 	
	 		//如果当前点的左下边未被设置 
	 		PointContainer= startPoint->getLeft_DownPoint(*startPoint);	//将要查询的点放入容器中 
	 		if(m_map_ipp[PointContainer->getX()][PointContainer->getY()] == -1)	
	 		{
	 			if(m_map_ipp[startPoint->getX()][startPoint->getY()] == '$') // 如果当前点为 $ ,设置成 . 
	 				m_map_ipp[PointContainer->getX()][PointContainer->getY()] = '.';
	 			if(m_map_ipp[startPoint->getX()][startPoint->getY()] == '.') // 如果当前点为 . ,设置成 $ 
	 				m_map_ipp[PointContainer->getX()][PointContainer->getY()] = '$';
	 		}
	 		//释放内存
	 		if(PointContainer != NULL)
	 			PointContainer->deletePoint(PointContainer);
	 		//如果当前点的下边未被设置 
	 		PointContainer= startPoint->getDownPoint(*startPoint);	//将要查询的点放入容器中 
	 		if(m_map_ipp[PointContainer->getX()][PointContainer->getY()] == -1)	
	 		{
	 			if(m_map_ipp[startPoint->getX()][startPoint->getY()] == '$') // 如果当前点为 $ ,设置成 . 
	 				m_map_ipp[PointContainer->getX()][PointContainer->getY()] = '.';
	 			if(m_map_ipp[startPoint->getX()][startPoint->getY()] == '.') // 如果当前点为 . ,设置成 $ 
	 				m_map_ipp[PointContainer->getX()][PointContainer->getY()] = '$';
	 		}
	 		//释放内存
	 		if(PointContainer != NULL)
	 			PointContainer->deletePoint(PointContainer);
	 		//进入下一行
			 if((startPoint->getX() !=markStartPoint->getX()*2) && startPoint->getY() == 1 && markFoot <= m_level_i/2 -2)
		 	{ 
		 		markFoot+=1;
		 		startPoint->setX(markStartPoint->getX()+markFoot);
		 		startPoint->setY(markStartPoint->getY());
		 	}
		 	else
		 		//没有到达最左,向左走;
		 		startPoint->setY(startPoint->getY()-1); 
	 	}while(startPoint->getX() != markStartPoint->getX()*2 && startPoint->getY()!= 0); 
	 	
	 	startPoint->deletePoint(startPoint);
		markStartPoint->deletePoint(markStartPoint);
	 }
void PrintGraphics::printMap(void) 
 	{
 		for(int i=0;i<m_level_i;++i)
 		{
 			for(int j=0;j<m_level_i;++j)
 			cout<<(char)m_map_ipp[i][j];
 			cout<<endl;	
 		}
 	}	

int main(void)
{
	int max;
	cin>>max;
	PrintGraphics pg1(max);
	pg1.printMap();
	
	return 0;
}

 

输出示例:

 

 

20180309155041872


 

评测结果:

20180309163933825

 

 

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
题目要求找出乱序整数序列中两数之和绝对值最小的两个数。 解题思路: 1. 首先对乱序整数序列进行排序,以便从小到大处理。 2. 将序列中的第一个和最后一个数相加,并记录绝对值作为当前最小值。 3. 初始化两个指针,一个指向序列的头部,一个指向序列的尾部。 4. 循环遍历序列,不断更新最小值并记录对应的两个数。 5. 每次迭代,如果当前两数之和的绝对值比之前的最小值小,则更新最小值和对应的两个数。 6. 若当前两数之和小于0,则将头指针向右移动一位;若当前两数之和大于0,则将尾指针向左移动一位;若当前两数之和等于0,则直接返回这两个数。 7. 重复步骤6直至头指针和尾指针相遇。 8. 返回最小值对应的两个数。 例如,对于序列[-5, 2, 7, -10, 9],排序后为[-10, -5, 2, 7, 9],初始化最小值为17(-10和7的和的绝对值),初始化指针为-10和9。 从左至右迭代,当前两数之和为-1,绝对值小于最小值17,则更新最小值为1,对应的两个数为-5和2。 向右移动头指针,当前两数之和为-3,绝对值小于最小值1,则更新最小值为3,对应的两个数为-5和7。 再向右移动头指针,当前两数之和为-8,绝对值小于最小值3,则更新最小值为8,对应的两个数为-10和7。 再向右移动头指针,两指针相遇,遍历结束。 最终,最小值为1,对应的两个数为-5和2。 综上所述,乱序整数序列两数之和绝对值最小为1,对应的两个数为-5和2。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值