1050 螺旋矩阵 (25分)
本题要求将给定的 N 个正整数按非递增的顺序,填入“螺旋矩阵”。所谓“螺旋矩阵”,是指从左上角第 1 个格子开始,按顺时针螺旋方向填充。要求矩阵的规模为 m 行 n 列,满足条件:m×n 等于 N;m≥n;且 m−n 取所有可能值中的最小值。
输入格式:
输入在第 1 行中给出一个正整数 N,第 2 行给出 N 个待填充的正整数。所有数字不超过 104,相邻数字以空格分隔。
输出格式:
输出螺旋矩阵。每行 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++真是好东西!!