给定一个长度为num的数列,先求出m,n使得m*n=N,并且m,n之间的差最小。之后构造旋转矩阵。设定一个二维数组dir表示四个方向,分别为右,下,左,上。设置每一次走的步数q,初始水平方向步数为n-1,垂直方向为m-1,每次转向后,步数因变成上一次在这个方向的步数-1。
特别要注意当num为质数时,处理不当可能会导致过不了测试点3,5。
#include<iostream>
#include<cmath>
#include<vector>
#include<algorithm>
using namespace std;
#define N 10005
vector<int> v;
int matrix[N][N];
int dir[4][2] = { { 0,1 },{ 1,0 },{ 0,-1 },{ -1,0 } };//right,down,left,up
bool cmp(int a,int b) {
return a > b;
}
int num;
int main() {
cin >> num;
v.resize(num);
int i, j, m, n;
for (i = 0;i<num;i++) {
cin >> v[i];
}
n=sqrt(num);
bool flag;
for (;n >= 1;n--) {
if (num%n == 0) {
m = num / n;
break;
}
}
sort(v.begin(), v.end(), cmp);
int k = 0, p = 0,q = n - 1,x=m-1,y=n-1;
i = j = 0;
flag = false;//flag控制这次是水平方向还是竖直方向
matrix[0][0] = v[k++];
while (k<num) {
//对q的判断如果放在循环的最后会导致过不了num为质数的情况
if (q == 0) {//当步数为0时应该转向
p = (p + 1) % 4;//改变方向
if (!flag) {
q = x--;//竖直方向
flag = true;
}
else {
flag = false;
q = y--;//水平方向
}
}
i += dir[p][0];
j += dir[p][1];
matrix[i][j] = v[k++];
q--;
}
for (i = 0;i<m;i++) {
cout << matrix[i][0];
for (j = 1;j<n;j++) {
cout << " " << matrix[i][j];
}
cout << endl;
}
//system("pause");
return 0;
}