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.
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.
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.
题目大意:将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、若数据放完了则退出循环。
#include <iostream> #include <vector> #include <algorithm> #include <cmath> using namespace std; vector <int> v; int N, index = 0, ans[10000][10000]; int getNum(int N); bool cmp(int a, int b); void leftToRight(int &left, int &right, int &top, int &bottom); void topToBottom(int &left, int &right, int &top, int &bottom); void rightToLeft(int &left, int &right, int &top, int &bottom); void bottomToTop(int &left, int &right, int &top, int &bottom); int main() { int m, n; scanf("%d", &N); v.resize(N); for(int i = 0; i < N; i++) scanf("%d", &v[i]); sort(v.begin(), v.end(), cmp); n = getNum(N); m = N / n; int left = 0, right = n-1, bottom = m-1, top = 0; while(index < N){ leftToRight(left, right, top, bottom); topToBottom(left, right, top, bottom); rightToLeft(left, right, top, bottom); bottomToTop(left, right, top, bottom); } for(int i = 0; i < m; i++){ for(int j = 0; j < n; j++){ printf("%d", ans[i][j]); if(j < n-1) printf(" "); } printf("\n"); } return 0; } void bottomToTop(int &left, int &right, int &top, int &bottom){ if(top > bottom || index >= N) return; for(int i = bottom; i>= top; i--){ ans[i][left] = v[index]; index++; } left++; } void rightToLeft(int &left, int &right, int &top, int &bottom){ if(left > right || index >= N) return; for(int i = right; i >= left; i--){ ans[bottom][i] = v[index]; index++; } bottom--; } void topToBottom(int &left, int &right, int &top, int &bottom){ if(top > bottom || index >= N) return; for(int i = top; i <= bottom; i++){ ans[i][right] = v[index]; index++; } right--; } void leftToRight(int &left, int &right, int &top, int &bottom){ if(left > right || index >= N) return; for(int i = left; i <= right; i++){ ans[top][i] = v[index]; index++; } top++; } int getNum(int N){ int n = sqrt(N); while(n > 1){ if(N % n == 0) break; n--; } return n; } bool cmp(int a, int b){ return a > b; }