PAT甲级 A1105
题目详情
1105 Spiral Matrix (25分)
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 10
4
. 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
2.建立矩阵,将数据实用sort函数从小到大排序
3.开始旋转,旋转时建立一个方向变量表示此时是向上填充,向右填充,向左填充或向下填充。判断边界条件使得向上填充变为向右填充,向右填充变为向下填充,向下填充变为向左填充,向左填充变为向上填充
以下为AC代码
#include<algorithm>
#include<iostream>
#include<vector>
#include<cmath>
#include<iomanip>
#include<map>
#include<queue>
#include<string>
using namespace std;
int N;
int INF = 1e9;
const int maxN = 200;
int ma[maxN][maxN];
int ques[10010];
int findmn(int N) {
int minst = INF;
int m = N;
for (int i = 2; i <= sqrt(N); i++) {
if (N % i == 0) {
int ca = max(i, N / i) - min(i, N / i);
if (ca < minst) {
minst = ca;
m = max(i, N / i);
}
}
}
return m;
}
bool cmp(int a, int b) {
return a > b;
}
int main() {
cin >> N;
for (int i = 0; i < N; i++) {
scanf_s("%d", &ques[i]);
}
int m, n;
m = findmn(N);
n = N / m;
sort(ques, ques + N,cmp);
string direction = "right";
fill(ma[0], ma[0] + 200 * 200, INF);
int cn = 0; int ln = 0;
for (int i = 0; i < N; i++) {;
ma[cn][ln] = ques[i];
if (direction == "right") {
if (ln == n - 1) {
cn = cn + 1;
direction = "down";
}
else if (ma[cn][ln + 1] != INF) {
cn = cn + 1;
direction = "down";
}
else {
ln = ln + 1;
}
continue;
}
else if (direction == "left") {
if (ln == 0) {
cn = cn - 1;
direction = "up";
}
else if (ma[cn][ln - 1] != INF) {
cn = cn - 1;
direction = "up";
}
else {
ln = ln - 1;
}
continue;
}
else if (direction == "up") {
if (cn == 0) {
ln = ln + 1;
direction = "right";
}
else if (ma[cn-1][ln] != INF) {
ln = ln + 1;
direction = "right";
}
else {
cn=cn-1;
}
continue;
}
else {
if (cn == m-1) {
ln = ln - 1;
direction = "left";
}
else if (ma[cn + 1][ln] != INF) {
ln = ln - 1;
direction = "left";
}
else {
cn = cn + 1;
}
continue;
}
}
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (j == 0) {
cout << ma[i][j];
}
else {
cout <<" "<<ma[i][j];
}
}
cout << '\n';
}
}