PAT甲级——1105 Spiral Matrix (螺旋矩阵)

此文同步发布在CSDN:https://blog.csdn.net/weixin_44385565/article/details/90484058

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; mn; and mn 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 1. 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

题目大意:将N个数字降序顺时针螺旋放入一个矩阵,然后输出矩阵。矩阵的行列数分别为m、n,要求m*n=N 且 m≥n、m-n最小。

思路:n取N的平方根,若N能被n整除,则符合条件,若不能,则n--继续寻找。螺旋放入矩阵有四个边界:left、right、top、bottom;写四个函数在边界之内按照四个方向往矩阵放入数据,进入循环:1、从左往右,到达右边界 right 的时候,top++(上边界往下压一层);2、从上到下,到达底部,right++;3、从右往左,到达左边界,bottom++;4、从下往上,到达上边界,left++;5、若数据放完了则退出循环。

 1 #include <iostream>
 2 #include <vector>
 3 #include <algorithm>
 4 #include <cmath>
 5 using namespace std;
 6 vector <int> v;
 7 int N,
 8     index = 0,
 9     ans[10000][10000];
10 int getNum(int N);
11 bool cmp(int a, int b);
12 void leftToRight(int &left, int &right, int &top, int &bottom);
13 void topToBottom(int &left, int &right, int &top, int &bottom);
14 void rightToLeft(int &left, int &right, int &top, int &bottom);
15 void bottomToTop(int &left, int &right, int &top, int &bottom);
16 int main()
17 {
18     int m, n;
19     scanf("%d", &N);
20     v.resize(N);
21     for(int i = 0; i < N; i++)
22         scanf("%d", &v[i]);
23     sort(v.begin(), v.end(), cmp);
24     n = getNum(N);
25     m = N / n;
26     int left = 0,
27         right = n-1,
28         bottom = m-1,
29         top = 0;
30     while(index < N){
31         leftToRight(left, right, top, bottom);
32         topToBottom(left, right, top, bottom);
33         rightToLeft(left, right, top, bottom);
34         bottomToTop(left, right, top, bottom);
35     }
36     for(int i = 0; i < m; i++){
37         for(int j = 0; j < n; j++){
38             printf("%d", ans[i][j]);
39             if(j < n-1)
40                 printf(" ");
41         }
42         printf("\n");
43     }
44     return 0;
45  } 
46  
47 void bottomToTop(int &left, int &right, int &top, int &bottom){
48     if(top > bottom || index >= N)
49         return;
50     for(int i = bottom; i>= top; i--){
51         ans[i][left] = v[index];
52         index++;
53     }
54     left++;
55 }
56  
57 void rightToLeft(int &left, int &right, int &top, int &bottom){
58     if(left > right || index >= N)
59         return;
60     for(int i = right; i >= left; i--){
61         ans[bottom][i] = v[index];
62         index++;
63     }
64     bottom--;
65 }
66  
67 void topToBottom(int &left, int &right, int &top, int &bottom){
68     if(top > bottom || index >= N)
69         return;
70     for(int i = top; i <= bottom; i++){
71         ans[i][right] = v[index];
72         index++;
73     }
74     right--;
75 }
76 
77 void leftToRight(int &left, int &right, int &top, int &bottom){
78     if(left > right || index >= N)
79         return;
80     for(int i = left; i <= right; i++){
81         ans[top][i] = v[index];
82         index++;
83     }
84     top++;
85 }
86  
87 int getNum(int N){
88     int n = sqrt(N);
89     while(n > 1){
90         if(N % n == 0)
91             break;
92         n--;
93     }
94     return n;
95 }
96 bool cmp(int a, int b){
97     return a > b;
98 }

 

posted @ 2019-05-23 17:21  大众名字重名太多  阅读(192)  评论(0编辑  收藏  举报