1050 螺旋矩阵 (25 分)

题目:1050 螺旋矩阵 (25 分)

 

本题要求将给定的 N 个正整数按非递增的顺序,填入“螺旋矩阵”。所谓“螺旋矩阵”,是指从左上角第 1 个格子开始,按顺时针螺旋方向填充。要求矩阵的规模为 m 行 n 列,满足条件:m×n 等于 N;mn;且 mn 取所有可能值中的最小值。

输入格式:

输入在第 1 行中给出一个正整数 N,第 2 行给出 N 个待填充的正整数。所有数字不超过 1,相邻数字以空格分隔。

输出格式:

输出螺旋矩阵。每行 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, 且mn 取所有可能值中的最小值,最快的方法就是对N开根号,根号前后满足的m和n就会是 m-n 中的最小值。这个规律是可以发现的,拿几个数来设想只要满足了就用,类似于数学归纳吧。比如9, 开根号得到3,3×3 确实是两约数的最小差。10开根号取整为3, 3不是约数就在根号前后找,找到2和5满足。不放心的话可以再找几个数,实际上这样差不多了,毕竟不是真的证数学归纳法。
  • 蛇形填数只要做好判断就没问题。在确定填数之前要判断有没有越界和有没有被填过了,填过的不重复填。然后注意++放变量前面和后面的区别。

代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cctype>
 4 #include <iostream>
 5 #include <sstream>
 6 #include <cmath>
 7 #include <algorithm>
 8 #include <string>
 9 #include <stack>
10 #include <queue>
11 #include <vector>
12 #include <map>
13 using namespace std;
14 
15 int a[10000][1000];
16 int num[10000]; 
17 
18 bool cmp(int a,int b)
19 {
20     return a > b;
21 }
22 
23 int main()
24 {
25     int n, m, r;
26     int minn=9999;
27        memset(a, 0, sizeof(a));
28     scanf("%d", &n);
29     for(int i = 0; i < n; i++)
30         scanf("%d", &num[i]);
31     sort(num, num + n, cmp);
32     for(int i = 1; i <= sqrt(n); i++)
33     {
34         if(n%i == 0 && minn > n/i-i)    //如果i是n的约数 && 两约数之差最小 
35         {           
36             minn = n / i - i;
37             r = i;    //r列
38             m = n / r;    //m行 
39         }        
40     }
41     n = 0;
42     int x = 0, y = 0;
43      a[x][y] = num[0];
44     while(n < m * r - 1)  //可要记得是从0开始数的
45     {
46         while(y + 1 < r && ! a[x][y + 1])
47             a[x][++y] = num[++n];
48         while(x + 1 < m && !a[x + 1][y])
49             a[++x][y] = num[++n];
50         while(y - 1 >= 0 && !a[x][y - 1])
51             a[x][--y] = num[++n];
52         while(x - 1 >= 0 && !a[x - 1][y])
53             a[--x][y] = num[++n];   
54     }
55     for(int i = 0; i < m; i++)
56     {
57         for(int j = 0; j < r; j++)
58         {
59             printf("%d",a[i][j]);
60             if(j != r-1)
61                 printf(" ");
62         } 
63         printf("\n");       
64     }
65     return 0;
66 }

 

总结:

  比较大的数组作为全局变量好像比局部变量要能扛一点。
  判断是不是约数时,竟一下没想到能否用取余判整除,用的是 n / i * i 是否等于 n,有点太死板。

posted @ 2019-08-20 16:13  Anzer  阅读(659)  评论(0编辑  收藏  举报