This time your job is to fill a sequence of N positive integers into a spiral matrix in non-increasing order. A spiral matrix is filled in from the first element at the upper-left corner, then move in a clockwise spiral. The matrix has m rows and n columns, where m and n satisfy the following: m×n must be equal to N; m≥n; and m−n is the minimum of all the possible values.
Input Specification:
Each input file contains one test case. For each case, the first line gives a positive integer N. Then the next line contains N positive integers to be filled into the spiral matrix. All the numbers are no more than 104. The numbers in a line are separated by spaces.
Output Specification:
For each test case, output the resulting matrix in m lines, each contains n numbers. There must be exactly 1 space between two adjacent numbers, and no extra space at the end of each line.
Sample Input:
12 37 76 20 98 76 42 53 95 60 81 58 93
Sample Output:
98 95 93 42 37 81 53 20 76 58 60 76
1.首先确定m和n,m比n大,且m是大于sqrt(n) && n % m最小整数。
2.设定边界up, right, down, left,然后沿边界进行循环,遇到边界符停止。
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn = 10010;
int matrix[maxn][maxn];
int seq[maxn] = { 0 };
bool cmp(int a, int b) {
return a > b;
}
int main() {
int N, m, n;
scanf("%d", &N);
for (int i = 0; i < N; i++) {
scanf("%d",&seq[i]);
}
sort(seq, seq + maxn, cmp);
double tmp = sqrt(N);
if (int(tmp)* int(tmp) == N)
{
m = n = tmp;
}
else {
m = (int)tmp + 1;
while (N % m != 0) {
m++;
}
n = N / m;
}
int up = 0, left = 0, right = n - 1, down = m - 1, index = 0;
while (index < N) {
int i = up, j = left;
do
{
matrix[i][j++] = seq[index++];
}while (j <= right);
j = right;
i++;
while (i < down)
{
matrix[i++][j] = seq[index++];
}
i = down;
while (j > left && index < N)
{
matrix[i][j--] = seq[index++];
}
j = left;
while (i > up && index < N)
{
matrix[i--][j] = seq[index++];
}
up++, right--, down--, left++;
}
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (j != 0) {
printf(" ");
}
printf("%d", matrix[i][j]);
}
printf("\n");
}
}
参照参考答案进行重构。
使用了ceil函数,逻辑简化。
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn = 10010;
int matrix[maxn][maxn];
int seq[maxn] = { 0 };
bool cmp(int a, int b) {
return a > b;
}
int main() {
int N, m, n;
scanf("%d", &N);
for (int i = 0; i < N; i++) {
scanf("%d", &seq[i]);
}
if (N == 1) { //一个元素是特例
printf("%d", seq[0]);
return 0;
}
sort(seq, seq + maxn, cmp);
m = (int)ceil(sqrt(N)); //使用ceil函数,大大简化代码
while (N % m != 0)
m++;
n = N / m;
int up = 0, left = 0, right = n - 1, down = m - 1, index = 0;
while (index < N) {
int i = up, j = left;
while (j < right && index < N) //当形成矩阵时,按边界遍历
{
matrix[i][j++] = seq[index++];
}
while (i < down && index < N)
{
matrix[i++][j] = seq[index++];
}
while (j > left&& index < N)
{
matrix[i][j--] = seq[index++];
}
while (i > up&& index < N)
{
matrix[i--][j] = seq[index++];
}
up++, right--, down--, left++;
if (index == N - 1) //如果只剩下一个元素
{
matrix[++i][++j] = seq[index];
break;
}
}
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (j != 0) {
printf(" ");
}
printf("%d", matrix[i][j]);
}
printf("\n");
}
return 0;
}