1105 Spiral Matrix 给定数组向螺旋矩阵中填入数据
两个测试用例超时,可直接跳转到
目录
超时点1
超时点2
要做的事情是,将数组按照非升序/降序,顺时针从外围到内部一圈一圈地把数据填到矩阵中,并打印出来。也就是将数组排好序后,将矩阵的坐标和数组的下标对应起来。
所以用一个这样的数组存放矩阵相应位置上元素的数组下标。
int mp[200][200] = {0};
起先,我这样填充每一圈(注意交点的分配)
当然,从外到内,这个圈一定是在减小的, 减小多少,我用z来控制,程序如下,4个for循环分别代表4条直线上的元素
int idx = n-1,i,j,z=1;int sw = false;//stop while循环 for(z=1;;z++){i = z;if(sw)break;for(j=z;j<=col-z;j++){mp[i][j] = idx--;
// printf("mp[%d][%d]=%d\n",i,j,idx+1);if(idx<0){sw = 1;break;}}j = col+1-z;if(sw)break;for(i=z;i<=row-z;i++){mp[i][j] = idx--;
// printf("mp[%d][%d]=%d\n",i,j,idx+1);if(idx<0){sw = 1;break;}}i = row+1-z;if(sw)break;for(j=col-z+1;j>=z+1;j--){mp[i][j] = idx--;
// printf("mp[%d][%d]=%d\n",i,j,idx+1);if(idx<0){sw = 1;break;}}j = z;if(sw)break;for(i=row-z+1;i>=z+1;i--){mp[i][j] = idx--;
// printf("mp[%d][%d]=%d\n",i,j,idx+1);if(idx<0){sw = 1;break;}}}
至于i和j的起止到底是多少,我也不能一下子想出,但我知道肯定有对称性,于是试了出来(通过被注释掉的打印)
特别说明一下变量sw,是stop while的缩写,用于跳出while循环,且每次进入for循环之前都要判断一下sw是否为true。idx<0说明矩阵已填满。
1)每次idx--之后都判断一下idx是否<0,但是此时break,只能跳出内层for循环,要跳出外层循环还要借助sw变量。
2)何时判断sw呢?我们希望达到的效果是idx<0一旦成立,就不再填充,如果只是在刚进入while循环的时候判断一下,可能出现的情况是,在第三个for循环中断后,又进入第四个for循环,所以每次进入循环前都要判断一下sw。
但是这样做,有两个测试用例是运行超时的。我迫切地翻开参考书,想看看自己究竟哪里代码不优雅了。
1)那个sw的判断希望下次不要再看到了。直接把idx>=0放在while和for的括号里不香吗?理论上while可以不放,但是这样光标一直闪,程序会出问题。改进后如下
int idx = n-1,i,j,z=1;for(z=1;idx>=0;z++){i = z;for(j=z;j<=col-z&&idx>=0;j++){mp[i][j] = idx--;}j = col+1-z;for(i=z;i<=row-z&&idx>=0;i++){mp[i][j] = idx--;}i = row+1-z;for(j=col-z+1;j>=z+1&&idx>=0;j--){mp[i][j] = idx--;}j = z;for(i=row-z+1;i>=z+1&&idx>=0;i--){mp[i][j] = idx--;}}
代码清爽了很多,但是超时的问题仍毫无进展。
超时点1
2)我听参考书的话,加入了如下特判
if(n==1){printf("%d",a[0]);return 0;}
于是从21变成了22分,有一个测试用例通过了。还剩一个超时,并且我注意到,刚才的两个超时,显示的时间都是-,也许是陷入了某种死循环。
3)我尝试提取i和j的边界中的公因子,引入
int r = col-z;
int d = row-z;
矩阵填充代码变成如下
int idx = n-1,i,j,z=1;for(z=1;idx>=0;z++){i = z;int r = col-z;int d = row-z;for(j=z;j<=r&&idx>=0;j++){mp[i][j] = idx--;}j = r+1;for(i=z;i<=d&&idx>=0;i++){mp[i][j] = idx--;}i = d+1;for(j=r+1;j>=z+1&&idx>=0;j--){mp[i][j] = idx--;}j = z;for(i=d+1;i>=z+1&&idx>=0;i--){mp[i][j] = idx--;}}
很遗憾,那个测试用例还是没过
4)最后,我又找出自己的代码和参考书代码的一个区别,那就是我在填充过程中填充的是数组下标,而参考书直接填充的内容,这样输出的时候就不必先映射到下标再输出,于是我照做。
将所有的
mp[i][j] = idx--;
改成了
mp[i][j] = a[idx--];
于是输出时候的
int idx = mp[i][j];
printf("%d",a[idx]);
也就自然变成了
printf("%d",mp[i][j]);
还是超时。。
超时点2
5)最后,我又发现,程序对最内层只有一个数字的情况进行了特判,也就是在4个for循环后加入了如下代码
i++;
j++;
if(idx==0)mp[i][j] = a[idx--];
好了,AC。
完整代码如下
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<vector>
#include<map>
#include<string>
#include<stdlib.h>using namespace std;const int maxn = 10010;int mp[200][200] = {0};int main(){int n;int a[maxn];scanf("%d",&n);for(int i=0;i<n;i++){scanf("%d",&a[i]);}if(n==1){printf("%d",a[0]);return 0;}int col,row;for(int i=(int)sqrt(n);i>=1;i--){if(n%i==0){col = i;break;}}row = n/col;//row>=col//a按照升序排好 sort(a,a+n);int idx = n-1,i,j,z;for(z=1;idx>=0;z++){int r = col-z;int d = row-z;for(i=z,j=z;j<=r&&idx>=0;j++){mp[i][j] = a[idx--];}for(i=z,j=r+1;i<=d&&idx>=0;i++){mp[i][j] = a[idx--];}for(i=d+1,j=r+1;j>=z+1&&idx>=0;j--){mp[i][j] = a[idx--];}for(i=d+1,j=z;i>=z+1&&idx>=0;i--){mp[i][j] = a[idx--];}i++;j++;if(idx==0)mp[i][j] = a[idx--];}for(int i=1;i<=row;i++){for(int j=1;j<=col;j++){printf("%d",mp[i][j]);if(j!=col)printf(" ");}printf("\n"); } return 0;
}
1105 Spiral Matrix 给定数组向螺旋矩阵中填入数据相关推荐
- Java黑皮书课后题第8章:**8.14(探讨矩阵)编写程序,提示用户输入一个方阵的长度,随机地在矩阵中填入0和1,打印这个矩阵,然后找出整行、整列或者对角线都是1或0的行、列和对角线
**8.14(探讨矩阵)编写程序,提示用户输入一个方阵的长度,随机地在矩阵中填入0和1,打印这个矩阵,然后找出整行.整列或者对角线都是1或0的行.列和对角线 题目 题目描述与运行示例 破题 代码 题目 ...
- C语言试题五之计算并输出给定数组(长度为9)中每相邻两个元素之平均值的平方根之和
1.题目 请编写函数function,它的功能是:计算并输出给定数组(长度为9)中每相邻两个元素之平均值的平方根之和 例子:若我们main函数给出double a[9] = {1, 2, 3, 4, ...
- 所谓“螺旋方阵”,是指对任意给定的N,将1到N×N的数字从左上角第1个格子开始,按顺时针螺旋方向顺序填入N×N的方阵里。本题要求构造这样的螺旋方阵。
所谓"螺旋方阵",是指对任意给定的N,将1到N×N的数字从左上角第1个格子开始,按顺时针螺旋方向顺序填入N×N的方阵里.本题要求构造这样的螺旋方阵. 这是最基本的思路 #inclu ...
- 螺旋方阵 螺旋方阵题目描述所谓“螺旋方阵”,是指对任意给定的N,将1到N×N的数字从左上角第1个格子开始,按顺时针螺旋方向顺序填入N×N的方阵里。
所谓"螺旋方阵",是指对任意给定的N,将1到N×N的数字从左上角第1个格子开始,按顺时针螺旋方向顺序填入N×N的方阵里.本题要求构造这样的螺旋方阵. 输入 输入在一行中给出一个正整 ...
- 把1,2,3…n*n 的数字按照顺时针螺旋的形式填入数字矩阵
从键盘输入一个整数(1~20) 则以该数字为矩阵的大小,把1,2,3-n*n 的数字按照顺时针螺旋的形式填入其中.例如: 输入数字2,则程序输出: 1 2 4 3 输入数字3,则程序输出: 1 2 3 ...
- sar点目标成像matlab,SARrawdata 根据矩阵中的高度数据,通过SAR点目标成像算法 过程,将 转换为实际从飞机 matlab 272万源代码下载- www.pudn.com...
文件名称: SARrawdata下载 收藏√ [ 5 4 3 2 1 ] 开发工具: matlab 文件大小: 1897 KB 上传时间: 2017-03-31 下载次数: 0 提 供 者 ...
- 4*4矩阵方格棋盘中,只能向方格中填入0或1,要使得棋盘的每行和没列的值的总和都是偶数,共有多少种可能性?
转自知乎:http://www.zhihu.com/question/20224638 4*4矩阵方格棋盘中,只能向方格中填入0或1,要使得棋盘的每行和没列的值的总和都是偶数,共有多少种可能性? 考虑 ...
- 随想录一期 day2 [977.有序数组的平方|209. 长度最小的子数组|59.螺旋矩阵II(剥洋葱)]
977.有序数组的平方 给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序. 思路 递增数组,平方后最大值一定在最左侧或者最右侧,可想到– ...
- 977. 有序数组的平方|209. 长度最小的子数组|59. 螺旋矩阵 II
977. 有序数组的平方 原理 准备:双指针.一个空数组.双指针指向的两个元素作比较,更大的数平方之后,放入空数组的尾部空位. 图解 其实这题的指针有两种方法: 从两边向中间靠拢,得到的是由大到小的值 ...
最新文章
- Failed to open zip file Gradle dependency cache be corrupt
- 关于深度残差收缩网络,你需要知道这几点
- 《2018-2019全球IPv6支持度白皮书》发布,江北新区IPv6示范区建设正式启动
- 如何画出漂亮的深度学习模型图
- SpikeSource公司的CEO-Kim Polese访谈
- 每天一点点之vue框架开发 - vue组件之间传值(父向子传值)
- Eclipse 版本升级:如何不卸载旧版本 Eclipse 实现在线升级到最新版本?
- 大型集团企业云管平台建设参考架构
- videoleap怎么导出本地_Pr导出视频时,如何调节视频文件大小?
- 格林时间转yyyy-MM-dd hh:mm:ss
- 贪吃蛇c语言代贴吧,【图片】C语言小游戏~贪吃蛇【c语言吧】_百度贴吧
- 阿里云企业邮箱使用步骤
- shell基础脚本命令记录
- vue请求接口报错405(Method Not Allowed)
- No active profile set, falling back to default profiles: default
- AHU HuffmanTree编码数据结构实验
- 声临其境,轻松几步教你把音频变成3D环绕音
- Inkscape制作LOGO——新手
- spark-2.2.0发行说明
- Java解一元二次方程和四则运算