PAT 乙級 1050 螺旋矩陣
阿新 • • 發佈:2019-01-11
1050 螺旋矩陣 (25 point(s))
本題要求將給定的 N 個正整數按非遞增的順序,填入“螺旋矩陣”。所謂“螺旋矩陣”,是指從左上角第 1 個格子開始,按順時針螺旋方向填充。要求矩陣的規模為 m 行 n 列,滿足條件:m×n 等於 N;m≥n;且 m−n 取所有可能值中的最小值。
輸入格式:
輸入在第 1 行中給出一個正整數 N,第 2 行給出 N 個待填充的正整數。所有數字不超過 104,相鄰數字以空格分隔。
輸出格式:
輸出螺旋矩陣。每行 n 個數字,共 m 行。相鄰數字以 1 個空格分隔,行末不得有多餘空格。
輸入樣例:
12
37 76 20 98 76 42 53 95 60 81 58 93
輸出樣例:
98 95 93
42 37 81
53 20 76
58 60 76
經驗總結:
emmmmmm 怎麼說呢,這一題其實思路上還是有點難度的,不知道怎麼控制輸出,實際上解決方法是按照順序控制下標一點點的填滿二維陣列,最後再按照二維陣列的規律輸出,詳細程式碼就在下面,這裡說一點,書上的程式碼提交後,最後一個測試點會超時(或者出錯?),我的解決方法是,對於所有的10^4以下的質數進行特判,因為質數N肯定是N行1列,如果用傳統的思路可能就會超時,特判的方式當然就是利用質數表啦~(๑•̀ㅂ•́)و✧
AC程式碼
#include <cstdio> #include <algorithm> #include <cmath> using namespace std; const int maxn=10010; int a[maxn],b[maxn][maxn]; bool flag[maxn]={false}; bool cmp(int a,int b) { return a>b; } void find_prime() { for(int i=2;i<maxn;++i) { if(flag[i]==false) { for(int j=i+i;j<maxn;j+=i) { flag[j]=true; } } } } void print(int row,int col) { for(int i=1;i<=row;++i) { for(int j=1;j<=col;++j) { printf("%d",b[i][j]); if(j!=col) printf(" "); else printf("\n"); } } } int main() { int n; find_prime(); while(~scanf("%d",&n)) { for(int i=0;i<n;++i) scanf("%d",&a[i]); if(n==1) { printf("%d",a[0]); } else if(flag[n]==false) { sort(a,a+n,cmp); for(int i=0;i<n;++i) printf("%d\n",a[i]); } else { sort(a,a+n,cmp); int row=(int)ceil(sqrt(1.0*n)); while(n%row!=0) ++row; int col=n/row; int U=1,D=row,L=1,R=col; int i=1,j=1,num=0; while(num<n) { while(j<R&&num<n) { b[i][j]=a[num++]; ++j; } while(i<D&&num<n) { b[i][j]=a[num++]; ++i; } while(j>L&&num<n) { b[i][j]=a[num++]; --j; } while(i>U&&num<n) { b[i][j]=a[num++]; --i; } ++U,--R,--D,++L; ++j;++i; if(num==n-1) { b[i][j]=a[num++]; } } print(row,col); } } return 0; }