PAT甲级——1105 Spiral Matrix (螺旋矩阵)
此文同步发布在CSDN:https://blog.csdn.net/weixin_44385565/article/details/90484058
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 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 }