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

题目描述

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

输入格式:

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

输出格式:

输出螺旋矩阵。每行 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

题目要求:

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

解题思路:

// 1、我们需要得到 螺旋矩阵 的行 row 与列 col 的值。

可以算出 n 的所有因子,然后找差值最小的两个因子。// 求出所有因子再计算差值有些复杂。

// 考虑到 相差最小的因子一定在 n 的平方根附近 若 n 是一个平方数,很明显最小差值的因子就是它的平方根

例如: n = 16 时,此时的 row = col = sqrt(n)

// 若 n 不是一个平方数,则从 n 的算术平方根 n0 开始往下枚举,枚举到 n 的一个因子的时候,即可得到符合题意的
// col 和 row 的值 例如: n = 10 时,sqrt(10) = 3 (因为col和row都是整型数据,自动取整) ,
但是 3 不是 10 的因子,所以往下枚举 2 , 2 是 10 的因子, 所以满足要求的 row = 5 ,col = 2 ( row >= col ) // 2、保存输入的 length 为 n 的数组,并从大到小排序 // 这里就是基础的 sort 函数运用了 ,存好数组,要求从大到小排序;手写一个与 sort 函数配合的 cmp 即可。 bool cmp(int a , int b){
return a > b ;
} sort(array,array + array.length() , cmp) ; // 我就是不想写 cmp 函数怎么办呢? 简单!
// 从大到小排序,我们知道,sort 函数是默认从小到大排序的,我把从小到大的数组,“倒”过来,不就是从大到小啦 sort(array,array + array.length()) ;
reverse(array,array + array.length()) ; // 3、准备工作做好了,剩下就是怎么将数组里的数,按照螺旋矩阵的要求,给我螺旋进一个二维数组了。
// 数组中有 n 个数要填入螺旋矩阵,所以结束的标志很容易想到是,记录填入了 x 个数,当 x < n 的时候,说明还要填。
int ans[10010][110] = { 0 } , array[10010] ;
int i = 0 , j = 0 , x = 0 ; // i 和 j 表示此时填的位置。
while( x < n ){
// 按照要求,先是从左往右填,所以是 i 保持不变 j 和 x 每次自增 1
/*
划重点,j < col 容易,因为最多也只有 col 列,为啥还需要 ans[i][j] == 0 呢?
因为,我们知道,如果 ans[i][j] 的值是 0 ,那么此时一定没有被前面某圈的螺旋矩阵填入数据,
反之,则这个位置已经被写入数据了,所以就不能继续此次赋值操作了,因为会覆盖以前的数据。
*/
while( j < col && ans[i][j] == 0)
ans[i][j++] = array[x++] ;
// 将需要的位置 拉回到下一起点。
j -- ;
i ++ ; // 右边 从上往下填, j 不变, i 和 x 自增
while( i < row && ans[i][j] == 0)
ans[i++][j] = array[x++] ;
// 将需要的位置 拉回到下一起点。
j -- ;
i -- ; // 下边 从右往左填, i 不变, j 自减 , x 自增
while( i < row && ans[i][j] == 0)
ans[i][j--] = array[x++] ;
// 将需要的位置 拉回到下一起点。
j ++ ;
i -- ; // 左边 从下往上填, j 不变, i 自减 , x 自增
while( i < row && ans[i][j] == 0)
ans[i--][j] = array[x++] ;
// 将需要的位置 拉回到下一起点。
j ++ ;
i ++ ;
} // 4、螺旋矩阵的输出,二维矩阵的输出,那就不是问题了
for(int i = 0 ; i < r ; i++){
cout << ans[i][0] ;
for(int j = 1 ; j < c ; j++){
cout<<" "<<ans[i][j] ;
}
cout<<endl ;
}

完整代码:

#include<bits/stdc++.h>
using namespace std ;
int ans[10010][110]={0} , num[100010] ;
int n ;
bool cmp(int a , int b){
return a > b ;
}
int main(){
cin >> n ;
for(int i = 0 ; i < n ; i++){
cin >> num[i] ;
}
sort(num , num + n , cmp) ;
int n0 = sqrt(n) , r = 1 , c , x = 0 ;// r为行,c为列
for(int i = n0 ; i >= 1 ; i--){
if(n % i == 0){
r = i ;
break ;
}
}
c = n / r ;
if(r < c) swap(r , c);
int i = 0 , j = 0 ;
while(x < n){
// 从左往右填
while( j < c && ans[i][j] == 0)
ans[i][j++] = num[x++] ;
j-- ;//调整下一条边的起点
i++ ;
// 右边从上往下填
while( i < r && ans[i][j] == 0)
ans[i++][j] = num[x++] ;
i-- ;//调整下一条边的起点
j-- ;
// 下边从右往左填
while( j >= 0 && ans[i][j] == 0)
ans[i][j--] = num[x++] ;
i-- ;//调整下一条边的起点
j++ ;
//从下往上填
while(i >= 0 && ans[i][j] == 0)
ans[i--][j] = num[x++] ;
i++ ;//调整为下一回合起点
j++ ;
}
for(int i = 0 ; i < r ; i++){
cout << ans[i][0] ;
for(int j = 1 ; j < c ; j++){
cout<<" "<<ans[i][j] ;
}
cout<<endl ;
}
return 0 ;
}

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. 动态规划算法 All In One

    动态规划算法 All In One dynamic programming leetcode https://leetcode.com/tag/dynamic-programming/ https:/ ...

  2. fullstack web projects in action

    fullstack web projects in action web 全栈项目实战 Angular 全栈 Angular + TypeScript + Nest.js + PostgreSQL + ...

  3. mobile css & rem & em & px

    mobile css & rem & em & px 1 rem === 16px 任意浏览器的默认字体高都是 16px, 所有未经调整的浏览器都符合: 1em=16px, 那 ...

  4. js 最简单的发布订阅模式

    let _subscriber: any; function autorun(subscriber: Function) { _subscriber = subscriber; _subscriber ...

  5. NGK.IO超级节点是我们掌握的下一个财富密码吗?

    从日前NGK.IO发布的新闻中,我们捕捉到了一个非常重要的信息,那就是反复被提到的"超级节点".很多人都对这个"超级节点"一头雾水,这个"超级节点&q ...

  6. Java审计之CMS中的那些反序列化漏洞

    Java审计之CMS中的那些反序列化漏洞 0x00 前言 过年这段时间比较无聊,找了一套源码审计了一下,发现几个有意思的点拿出来给分享一下. 0x01 XStream 反序列化漏洞 下载源码下来发现并 ...

  7. 两年Java,去字节跳动写Python和Go

    前言 2019年5月,在收到offer邮件的那一刻,我仍然不敢相信自己这一番际遇.经历了七场面试,终于得偿所望,拿到了字节跳动的offer. 做加入大厂的决定并不是巧合.在多年的职业生涯里,我曾多次对 ...

  8. vue的el-select标签全选以及出现需要有禁用选项

    首先说一下遇到这种问题的解决思路吧,很简单先去https://element.eleme.cn/#/zh-CN 这个官网上找到对应的需求,然后就是拼接数据的问题. 以下是全选的例子: <el-s ...

  9. Prism -- 简介

    Prism是一个开源框架,用于在WPF.Xamarin Forms.Uno/Win UI等应用中创建松耦合.可维护.可测试的XAML应用程序.Prism提供了一组设计模式的实现,这些设计模式有助于编写 ...

  10. entitybuilder--一个简单的业务通用框架

    关于业务通用框架的思考 业务系统是千差万别的,例如,保存.更新和删除订单,或者保存订单和保存客户,走的根本不是一个流程.但是,它们还是有共同点,它们的流程大致可以分成下面的几个部分: 拿到增删改等操作 ...