PAT1050
阿新 • • 發佈:2019-01-07
本題要求將給定的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;
}
- 開根號定義在math.h
- 當N=11*21時,開根號後得到的數一定位於m和n之間。通過遞減直到餘數為0
- 通過vector構造二維陣列。
- 在判斷是否需要調整方向時,是3個或。注意只要前面有條件為真,就不再進行後面的判斷。(參考的做法使用的是內建陣列,可以向前(下標為-1)越界訪問,但是vector不行。所以改進將判斷內容是否為0放在最後)
- 判斷內容是否為0用於陣列內層的迭代;判斷x和y是否越界用於外層迴圈
- 通過dircted陣列決定方向。大大減少了程式設計的複雜程度。