PAT (Basic Level) Practice (中文) 1050 螺旋矩阵 (25 分)

题目描述

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

输入格式:

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

输出格式:

  1. 输出螺旋矩阵。每行 n 个数字,共 m 行。相邻数字以 1 个空格分隔,行末不得有多余空格。

输入样例:

  1. 12
  2. 37 76 20 98 76 42 53 95 60 81 58 93

输出样例:

  1. 98 95 93
  2. 42 37 81
  3. 53 20 76
  4. 58 60 76

题目要求:

  1. 作者 CHEN, Yue
  2. 单位 浙江大学
  3. 代码长度限制 16 KB
  4. 时间限制 400 ms
  5. 内存限制 64 MB

解题思路:

  1. // 1、我们需要得到 螺旋矩阵 的行 row 与列 col 的值。
  2. 可以算出 n 的所有因子,然后找差值最小的两个因子。// 求出所有因子再计算差值有些复杂。
  3. // 考虑到 相差最小的因子一定在 n 的平方根附近 若 n 是一个平方数,很明显最小差值的因子就是它的平方根
  4. 例如: n = 16 时,此时的 row = col = sqrt(n)
  5. // 若 n 不是一个平方数,则从 n 的算术平方根 n0 开始往下枚举,枚举到 n 的一个因子的时候,即可得到符合题意的
  6. // col 和 row 的值
  7. 例如: n = 10 时,sqrt(10) = 3 (因为colrow都是整型数据,自动取整)
  8. 但是 3 不是 10 的因子,所以往下枚举 2 2 10 的因子, 所以满足要求的 row = 5 col = 2 ( row >= col )
  9. // 2、保存输入的 length 为 n 的数组,并从大到小排序
  10. // 这里就是基础的 sort 函数运用了 ,存好数组,要求从大到小排序;手写一个与 sort 函数配合的 cmp 即可。
  11. bool cmp(int a , int b){
  12. return a > b ;
  13. }
  14. sort(array,array + array.length() , cmp) ;
  15. // 我就是不想写 cmp 函数怎么办呢? 简单!
  16. // 从大到小排序,我们知道,sort 函数是默认从小到大排序的,我把从小到大的数组,“倒”过来,不就是从大到小啦
  17. sort(array,array + array.length()) ;
  18. reverse(array,array + array.length()) ;
  19. // 3、准备工作做好了,剩下就是怎么将数组里的数,按照螺旋矩阵的要求,给我螺旋进一个二维数组了。
  20. // 数组中有 n 个数要填入螺旋矩阵,所以结束的标志很容易想到是,记录填入了 x 个数,当 x < n 的时候,说明还要填。
  21. int ans[10010][110] = { 0 } , array[10010] ;
  22. int i = 0 , j = 0 , x = 0 ; // i 和 j 表示此时填的位置。
  23. while( x < n ){
  24. // 按照要求,先是从左往右填,所以是 i 保持不变 j 和 x 每次自增 1
  25. /*
  26. 划重点,j < col 容易,因为最多也只有 col 列,为啥还需要 ans[i][j] == 0 呢?
  27. 因为,我们知道,如果 ans[i][j] 的值是 0 ,那么此时一定没有被前面某圈的螺旋矩阵填入数据,
  28. 反之,则这个位置已经被写入数据了,所以就不能继续此次赋值操作了,因为会覆盖以前的数据。
  29. */
  30. while( j < col && ans[i][j] == 0)
  31. ans[i][j++] = array[x++] ;
  32. // 将需要的位置 拉回到下一起点。
  33. j -- ;
  34. i ++ ;
  35. // 右边 从上往下填, j 不变, i 和 x 自增
  36. while( i < row && ans[i][j] == 0)
  37. ans[i++][j] = array[x++] ;
  38. // 将需要的位置 拉回到下一起点。
  39. j -- ;
  40. i -- ;
  41. // 下边 从右往左填, i 不变, j 自减 , x 自增
  42. while( i < row && ans[i][j] == 0)
  43. ans[i][j--] = array[x++] ;
  44. // 将需要的位置 拉回到下一起点。
  45. j ++ ;
  46. i -- ;
  47. // 左边 从下往上填, j 不变, i 自减 , x 自增
  48. while( i < row && ans[i][j] == 0)
  49. ans[i--][j] = array[x++] ;
  50. // 将需要的位置 拉回到下一起点。
  51. j ++ ;
  52. i ++ ;
  53. }
  54. // 4、螺旋矩阵的输出,二维矩阵的输出,那就不是问题了
  55. for(int i = 0 ; i < r ; i++){
  56. cout << ans[i][0] ;
  57. for(int j = 1 ; j < c ; j++){
  58. cout<<" "<<ans[i][j] ;
  59. }
  60. cout<<endl ;
  61. }

完整代码:

  1. #include<bits/stdc++.h>
  2. using namespace std ;
  3. int ans[10010][110]={0} , num[100010] ;
  4. int n ;
  5. bool cmp(int a , int b){
  6. return a > b ;
  7. }
  8. int main(){
  9. cin >> n ;
  10. for(int i = 0 ; i < n ; i++){
  11. cin >> num[i] ;
  12. }
  13. sort(num , num + n , cmp) ;
  14. int n0 = sqrt(n) , r = 1 , c , x = 0 ;// r为行,c为列
  15. for(int i = n0 ; i >= 1 ; i--){
  16. if(n % i == 0){
  17. r = i ;
  18. break ;
  19. }
  20. }
  21. c = n / r ;
  22. if(r < c) swap(r , c);
  23. int i = 0 , j = 0 ;
  24. while(x < n){
  25. // 从左往右填
  26. while( j < c && ans[i][j] == 0)
  27. ans[i][j++] = num[x++] ;
  28. j-- ;//调整下一条边的起点
  29. i++ ;
  30. // 右边从上往下填
  31. while( i < r && ans[i][j] == 0)
  32. ans[i++][j] = num[x++] ;
  33. i-- ;//调整下一条边的起点
  34. j-- ;
  35. // 下边从右往左填
  36. while( j >= 0 && ans[i][j] == 0)
  37. ans[i][j--] = num[x++] ;
  38. i-- ;//调整下一条边的起点
  39. j++ ;
  40. //从下往上填
  41. while(i >= 0 && ans[i][j] == 0)
  42. ans[i--][j] = num[x++] ;
  43. i++ ;//调整为下一回合起点
  44. j++ ;
  45. }
  46. for(int i = 0 ; i < r ; i++){
  47. cout << ans[i][0] ;
  48. for(int j = 1 ; j < c ; j++){
  49. cout<<" "<<ans[i][j] ;
  50. }
  51. cout<<endl ;
  52. }
  53. return 0 ;
  54. }

PAT (Basic Level) Practice (中文) 1050 螺旋矩阵 (25 分) 凌宸1642的更多相关文章

  1. PAT (Advanced Level) Practice 1027 Colors in Mars (20 分) 凌宸1642

    PAT (Advanced Level) Practice 1027 Colors in Mars (20 分) 凌宸1642 题目描述: People in Mars represent the c ...

  2. PAT (Advanced Level) Practice 1019 General Palindromic Number (20 分) 凌宸1642

    PAT (Advanced Level) Practice 1019 General Palindromic Number (20 分) 凌宸1642 题目描述: A number that will ...

  3. PAT (Advanced Level) Practice 1011 World Cup Betting (20 分) 凌宸1642

    PAT (Advanced Level) Practice 1011 World Cup Betting (20 分) 凌宸1642 题目描述: With the 2010 FIFA World Cu ...

  4. PAT (Advanced Level) Practice 1005 Spell It Right (20 分) 凌宸1642

    PAT (Advanced Level) Practice 1005 Spell It Right (20 分) 凌宸1642 题目描述: Given a non-negative integer N ...

  5. PAT (Advanced Level) Practice 1001 A+B Format (20 分) 凌宸1642

    PAT (Advanced Level) Practice 1001 A+B Format (20 分) 凌宸1642 题目描述: Calculate a+b and output the sum i ...

  6. PAT (Basic Level) Practice (中文)1055 集体照 (25 分) 凌宸1642

    PAT (Basic Level) Practice (中文)1055 集体照 (25 分) 凌宸1642 题目描述: 拍集体照时队形很重要,这里对给定的 N 个人 K 排的队形设计排队规则如下: 每 ...

  7. PAT (Basic Level) Practice (中文)1070 结绳 (25 分) 凌宸1642

    PAT (Basic Level) Practice (中文)1070 结绳 (25 分) 凌宸1642 题目描述 给定一段一段的绳子,你需要把它们串成一条绳.每次串连的时候,是把两段绳子对折,再如下 ...

  8. PAT (Basic Level) Practice (中文)1065 单身狗 (25 分) 凌宸1642

    PAT (Basic Level) Practice (中文)1065 单身狗 (25 分) 凌宸1642 题目描述: "单身狗"是中文对于单身人士的一种爱称.本题请你从上万人的大 ...

  9. PAT (Advanced Level) Practice 1006 Sign In and Sign Out (25 分) 凌宸1642

    PAT (Advanced Level) Practice 1006 Sign In and Sign Out (25 分) 凌宸1642 题目描述: At the beginning of ever ...

随机推荐

  1. js 在浏览器中使用 monaco editor

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...

  2. 新年狂欢高倍币,1万枚VAST拿到手软

    新一年NGK推出了新币VAST,成为了当前最瞩目的一颗星.有人认为VAST有价无市,有人认为VAST价值巨大,潜力无限.总之,众说风云! 选择数字货币,当然是挑选有价值的货币,从内外价值入手. 一.币 ...

  3. django学习-25.admin管理后台里:把表名称和表字段名称的展示值都由英文显示改为由中文显示

    目录结构 1.前言 2.完整的操作步骤 2.1.第一步:修改模型类Article 2.2.第二步:重启服务 2.3.第三步:退出登录并再次成功登陆admin管理后台 2.4.第四步:查看最新的表名称展 ...

  4. GridSearchCV网格搜索得到最佳超参数, 在K近邻算法中的应用

    最近在学习机器学习中的K近邻算法, KNeighborsClassifier 看似简单实则里面有很多的参数配置, 这些参数直接影响到预测的准确率. 很自然的问题就是如何找到最优参数配置? 这就需要用到 ...

  5. img图片默认的3px空白缝隙解决方法

    img{display:block;} 表示将img标签,即图片标签由行内元素变成一个块级元素. 一般在制作轮播网页或使用到img图片时,我们都会对图片设置img{display:bolck}.因为i ...

  6. close() 和fluse()区别

    1.close()默认包含了一次flush()操作,关闭之后,就不能再写入了. 2.flush()刷新,flush()之后,可以接着写入. 3.缓冲区默认大小是8192字节,如果小于8192字节,不会 ...

  7. IO、NIO、BIO的区别

    我们首先得明白什么是同步,异步,阻塞,非阻塞,只有这几个单个概念理解清楚了,然后在组合理解起来,就相对比较容易了. IO模型主要分类: 同步(synchronous) IO和异步(asynchrono ...

  8. 看完我的笔记不懂也会懂----javascript模块化

    JavaScript模块化 模块化引子 模块化的历史进化 模块化规范 CommonJS规范 Node.js(服务器端) 下项目的结构分析 browerify(浏览器端) 下项目的结构分析 AMD规范 ...

  9. 剑指 Offer 19. 正则表达式匹配 + 动态规划

    剑指 Offer 19. 正则表达式匹配 题目链接 一. 字符串匹配大致可以分为三种情况: 第一种:正则串的最后一个字符为正常字符,此时根据主串的最后一个字符是否和它相同来判断是否匹配, 如果相同,则 ...

  10. 翻译:《实用的Python编程》03_05_Main_module

    目录 | 上一节 (3.4 模块) | 下一节 (3.6 设计讨论) 3.5 主模块 本节介绍主程序(主模块)的概念 主函数 在许多编程语言中,存在一个主函数或者主方法的概念. // c / c++ ...