PAT乙级1050螺旋矩阵(用走迷宫的思路来思考,挺简单的)

                                                                       1050 螺旋矩阵 (25分)

本题要求将给定的 N 个正整数按非递增的顺序,填入“螺旋矩阵”。所谓“螺旋矩阵”,是指从左上角第 1 个格子开始,按顺时针螺旋方向填充。要求矩阵的规模为 m 行 n 列,满足条件:m×n 等于 N;m≥n;且 m−n 取所有可能值中的最小值。

输入格式:

输入在第 1 行中给出一个正整数 N,第 2 行给出 N 个待填充的正整数。所有数字不超过 10​4​​,相邻数字以空格分隔。

输出格式:

输出螺旋矩阵。每行 n 个数字,共 m 行。相邻数字以 1 个空格分隔,行末不得有多余空格。

输入样例:

12
37 76 20 98 76 42 53 95 60 81 58 93

输出样例:

98 95 93
42 37 81
53 20 76
58 60 76

 

 

思路很简单

1.首先计算出输入数据所组成矩阵需要的行数row,与列数column;

2.将输入的数据从大到小排序,做好使用准备。

3.类似于走迷宫,构建一个[row+2,column+2]的大矩阵,最外围看做是墙,然后从(1,1)坐标开始出发,先一路向右(没遇到墙的格子就可以放数据了),遇到“围墙”则一路向下;再遇到墙就一路向左;接着一路向上。。。不停重复这个走迷宫行为,直到

数据用完。

#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<climits>
using namespace std;
bool cmp(int a, int b)
{
	return a > b;
}
int main()
{   
	int max = INT_MAX,di=0,br=1,bl=1;
	int N,row,column,k;
	cin >> N;
	vector<int>arrys(N);
	for (int i = 1; i <=N; i++) //确定几行几列
	{   
		cin >> arrys[i - 1];
		for (int j = 1; j <= N; j++)
		{
			if (i*j == N && (i >= j) && (i - j) < max)
			{   
				max = i-j;
				row = i;
				column = j;
			}
		}
	}
	sort(arrys.begin(), arrys.end(), cmp);
	vector < vector<int>>mg;//迷宫标记,最先开始最外围全是墙
	vector < vector<int>>mgdata;//放数据
	mg.resize(row+2);//vectory二维数组的初始化(行)
	mgdata.resize(row + 2);
	for (int i = 0; i < row + 2; i++)//vectory二维数组的初始化(列)
	{
		mg[i].resize(column +2);
		mgdata[i].resize(column + 2);
	}//二维数组初始化
	for (int j = 0; j <column + +2; j++)
	{
		mg[0][j] = -1;
		mg[row + 1][j] = -1;
	}

	for (int i = 0; i < row + 2; i++)//初始化边界造墙
	{
		mg[i][0] = -1;
		mg[i][column + 1] = -1;
	}//边界包围着
	mgdata[1][1] = arrys[0]; //迷宫入口为(1,1)
	mg[1][1] = -1;//走过的格子可以做好标记了,-1代表走过,也代表墙
	k = N;
	k--;
	int u = 1;
	while (k>0)
	{   
		di = 1;//先扫最右边
		while (di == 1)
		{   
			bl++;
			//cout << br << ":" << bl << endl;
			if (mg[br][bl] == -1)
			{   
				bl--;//复位
				di = 2;
				break;
			}
			mgdata[br][bl] = arrys[u++];
			mg[br][bl] = -1;
			k--;
		}//一直往右边扫完,扫下边
		while (di == 2)
		{   
			br++;
			//cout << br << ":" << bl << endl;
			if (mg[br][bl] == -1)
			{   
				br--;
				di = 3;
				break;
			}
			mgdata[br][bl] = arrys[u++];
			mg[br][bl] = -1;
			k--;
		}
		while (di == 3)//扫左边
		{   
			bl--;
			//cout << br << ":" << bl << endl;
			if (mg[br][bl] == -1)
			{
				bl++;
				di = 4;
				break;
			}
			mgdata[br][bl] = arrys[u++];
			mg[br][bl] = -1;
			k--;
		}
		while (di == 4)//扫上边
		{   
			br--;
			//cout << br << ":" << bl << endl;
			if (mg[br][bl] == -1)
			{
				br++;
				break;
			}
			mgdata[br][bl] = arrys[u++];
			mg[br][bl] = -1;
			k--;
		}
	}
	for (int i = 1; i <= row; i++) 
	{
		for (int j = 1; j <= column; j++)
		{
			if (j != 1){
				cout << " ";
			}
			cout << mgdata[i][j];
			if (j == column)
			{
				cout << endl;
			}
		}
	}
	return 0;
}

总结:

vctory的二维数组用到了,初始化方法还是有点冷门

这算是深度优先算法的开胃菜吧,因为原来看过走迷宫的题,所以有点思路

走迷宫算法那里写的有点冗长了,精简下应该看着更简单,舒适

c++真是好东西!!

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值