1050 螺旋矩陣——c實現
阿新 • • 發佈:2018-11-11
1050 螺旋矩陣 (25 分)
本題要求將給定的 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
思路:
這道題的難點總共有兩點,第一點是確定m*n;第二點是如何能夠列印螺旋矩陣。
第一個問題比較簡單,只需要對讓n=(int)sqrt(n),然後N%n==0,如果不滿足,則n--,就會找到合適的m,n。
第二個問題稍微麻煩一些,關鍵是要有處理類似問題的經驗,首先將封閉的一圈作為一個研究物件,而一圈又包含上下左右四個矩形邊的輸出,這裡就可以看到需要兩個for迴圈。注意每行的特點,一個圈子中的最上行,存資料時,行數不變列數增加;最右邊則是列數不變行數減小……依次就可以儲存進二維陣列。
注意點:還有需要注意的是如何確定螺旋轉多少圈的問題,畫了4*3的矩陣和4*4的矩陣來幫助分析,他們都是轉兩圈雖然第二圈值轉到中途。即其實每轉一圈需要用掉兩列,如果是偶數列即為n/2求圈數便可,但如果是奇數列n/2還會剩下一列同樣要轉圈,所以應該是n/2+n%2,這樣在偶數的時候取餘不起作用,在奇數的時候又可以多加1圈。
程式碼:
//1050 螺旋矩陣 v1 #include <stdio.h> #include <math.h> #include <stdlib.h> int cmp(const void* a,const void* b){ return *(int*)b-*(int*)a; //b-a是降序,a-b是升序 } int main(){ int N,n,m,i,j; scanf("%d",&N); int a[N]; for(n=0;n<N;n++) scanf("%d",&a[n]); qsort(a,N,sizeof(int),cmp); n=(int)(sqrt(N)); //i是n while(N%n!=0){ //不能整除 n--; } m=N/n; //j is m // printf("%d %d\n",m,n); int mat[m][n]; int urow=0,drow=m-1,lcol=0,rcol=n-1,k; for(k=n/2+n%2;k>=0;k--){ //從外到裡遍歷的圈數 for(j=lcol;j<=rcol&&i!=N;j++,i++) //遍歷最上行 mat[urow][j]=a[i]; urow++; //最上行遍歷完畢 for(j=urow;j<=drow&&i!=N;j++,i++) //遍歷最右列 mat[j][rcol]=a[i]; rcol--; for(j=rcol;j>=lcol&&i!=N;j--,i++) mat[drow][j]=a[i]; drow--; for(j=drow;j>=urow&&i!=N;j--,i++) mat[j][lcol]=a[i]; lcol++; } for(i=0;i<m;i++){ for(j=0;j<n;j++){ if(j==n-1) printf("%d\n",mat[i][j]); else printf("%d ",mat[i][j]); } } return 0; }
參考: