1. 程式人生 > >PAT1050

PAT1050

本題要求將給定的N個正整數按非遞增的順序,填入“螺旋矩陣”。所謂“螺旋矩陣”,是指從左上角第1個格子開始,按順時針螺旋方向填充。要求矩陣的規模為m行n列,滿足條件:m*n等於N;m>=n;且m-n取所有可能值中的最小值。

#include<iostream>
#include<vector>
#include<algorithm>
#include <math.h> 
using namespace std;

int main() {

    int N;
    cin >> N;
    vector<int>
A(N); for (int i = 0;i<N;i++) cin >> A[i]; //當只輸入一個數時直接輸出 if (N == 1) { cout << A[0] << endl; return 0; } sort(A.begin(), A.end()); int a=sqrt(N); while (N % a != 0) --a; int c= N / a; int m = c, n = a; vector< vector
<int>
>
B(m, vector<int>(n, 0)); int direct[] = { 0,1,2,3 }, d = 0, posD = 0; //控制方向:向右,向下,向左,向上。 int x = 0, y = 0, posA = N-1; while (posA>=0) { if ((x == m || x<0) || (y == n || y<0)|| B[x][y] != 0)//方向調轉,碰到邊界或者下一個數已經 { ++posD; switch
(d) //之前已經超過邊界一格了,所以要回退一步。 { case 0: y--;x++;break; case 1:x--;y--;break; case 2:y++;x--;break; case 3: x++;y++;break; } d = direct[posD % 4]; } B[x][y] = A[posA];--posA; //往二維陣列填充資料。 switch (d) //一直往上面設定的方向行走和填充。 { case 0: y++;break; case 1:x++;break; case 2:y--;break; case 3: x--;break; } } for (int h = 0;h<m;h++) //列印結果 { for (int l = 0;l<n;l++) { cout << B[h][l]; if (l != n - 1) { cout << " "; } } cout << endl; } return 0; }
  1. 開根號定義在math.h
  2. 當N=11*21時,開根號後得到的數一定位於m和n之間。通過遞減直到餘數為0
  3. 通過vector構造二維陣列。
  4. 在判斷是否需要調整方向時,是3個或。注意只要前面有條件為真,就不再進行後面的判斷。(參考的做法使用的是內建陣列,可以向前(下標為-1)越界訪問,但是vector不行。所以改進將判斷內容是否為0放在最後)
  5. 判斷內容是否為0用於陣列內層的迭代;判斷x和y是否越界用於外層迴圈
  6. 通過dircted陣列決定方向。大大減少了程式設計的複雜程度。