两个测试用例超时,可直接跳转到

目录

超时点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 给定数组向螺旋矩阵中填入数据相关推荐

  1. Java黑皮书课后题第8章:**8.14(探讨矩阵)编写程序,提示用户输入一个方阵的长度,随机地在矩阵中填入0和1,打印这个矩阵,然后找出整行、整列或者对角线都是1或0的行、列和对角线

    **8.14(探讨矩阵)编写程序,提示用户输入一个方阵的长度,随机地在矩阵中填入0和1,打印这个矩阵,然后找出整行.整列或者对角线都是1或0的行.列和对角线 题目 题目描述与运行示例 破题 代码 题目 ...

  2. C语言试题五之计算并输出给定数组(长度为9)中每相邻两个元素之平均值的平方根之和

    1.题目 请编写函数function,它的功能是:计算并输出给定数组(长度为9)中每相邻两个元素之平均值的平方根之和 例子:若我们main函数给出double a[9] = {1, 2, 3, 4, ...

  3. 所谓“螺旋方阵”,是指对任意给定的N,将1到N×N的数字从左上角第1个格子开始,按顺时针螺旋方向顺序填入N×N的方阵里。本题要求构造这样的螺旋方阵。

    所谓"螺旋方阵",是指对任意给定的N,将1到N×N的数字从左上角第1个格子开始,按顺时针螺旋方向顺序填入N×N的方阵里.本题要求构造这样的螺旋方阵. 这是最基本的思路 #inclu ...

  4. 螺旋方阵 螺旋方阵题目描述所谓“螺旋方阵”,是指对任意给定的N,将1到N×N的数字从左上角第1个格子开始,按顺时针螺旋方向顺序填入N×N的方阵里。

    所谓"螺旋方阵",是指对任意给定的N,将1到N×N的数字从左上角第1个格子开始,按顺时针螺旋方向顺序填入N×N的方阵里.本题要求构造这样的螺旋方阵. 输入 输入在一行中给出一个正整 ...

  5. 把1,2,3…n*n 的数字按照顺时针螺旋的形式填入数字矩阵

    从键盘输入一个整数(1~20) 则以该数字为矩阵的大小,把1,2,3-n*n 的数字按照顺时针螺旋的形式填入其中.例如: 输入数字2,则程序输出: 1 2 4 3 输入数字3,则程序输出: 1 2 3 ...

  6. sar点目标成像matlab,SARrawdata 根据矩阵中的高度数据,通过SAR点目标成像算法 过程,将 转换为实际从飞机 matlab 272万源代码下载- www.pudn.com...

    文件名称: SARrawdata下载  收藏√  [ 5  4  3  2  1 ] 开发工具: matlab 文件大小: 1897 KB 上传时间: 2017-03-31 下载次数: 0 提 供 者 ...

  7. 4*4矩阵方格棋盘中,只能向方格中填入0或1,要使得棋盘的每行和没列的值的总和都是偶数,共有多少种可能性?

    转自知乎:http://www.zhihu.com/question/20224638 4*4矩阵方格棋盘中,只能向方格中填入0或1,要使得棋盘的每行和没列的值的总和都是偶数,共有多少种可能性? 考虑 ...

  8. 随想录一期 day2 [977.有序数组的平方|209. 长度最小的子数组|59.螺旋矩阵II(剥洋葱)]

    977.有序数组的平方 给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序. 思路 递增数组,平方后最大值一定在最左侧或者最右侧,可想到– ...

  9. 977. 有序数组的平方|209. 长度最小的子数组|59. 螺旋矩阵 II

    977. 有序数组的平方 原理 准备:双指针.一个空数组.双指针指向的两个元素作比较,更大的数平方之后,放入空数组的尾部空位. 图解 其实这题的指针有两种方法: 从两边向中间靠拢,得到的是由大到小的值 ...

最新文章

  1. Failed to open zip file Gradle dependency cache be corrupt
  2. 关于深度残差收缩网络,你需要知道这几点
  3. 《2018-2019全球IPv6支持度白皮书》发布,江北新区IPv6示范区建设正式启动
  4. 如何画出漂亮的深度学习模型图
  5. SpikeSource公司的CEO-Kim Polese访谈
  6. 每天一点点之vue框架开发 - vue组件之间传值(父向子传值)
  7. Eclipse 版本升级:如何不卸载旧版本 Eclipse 实现在线升级到最新版本?
  8. 大型集团企业云管平台建设参考架构
  9. videoleap怎么导出本地_Pr导出视频时,如何调节视频文件大小?
  10. 格林时间转yyyy-MM-dd hh:mm:ss
  11. 贪吃蛇c语言代贴吧,【图片】C语言小游戏~贪吃蛇【c语言吧】_百度贴吧
  12. 阿里云企业邮箱使用步骤
  13. shell基础脚本命令记录
  14. vue请求接口报错405(Method Not Allowed)
  15. No active profile set, falling back to default profiles: default
  16. AHU HuffmanTree编码数据结构实验
  17. 声临其境,轻松几步教你把音频变成3D环绕音
  18. Inkscape制作LOGO——新手
  19. spark-2.2.0发行说明
  20. Java解一元二次方程和四则运算

热门文章

  1. mpvue 转uni-app 操作记录
  2. 离群点检测算法-基础概念
  3. 第36章 网络管理
  4. 手动建库11.2.0.4
  5. Linux编程之自定义消息队列
  6. wifidog接口文档(转)
  7. 【Go语言】LiteIDE使用的个人使用方法
  8. PHP学习笔记 第八讲 Mysql.简介和创建新的数据库
  9. hadoop源码datanode序列图
  10. linux下如何查看某个软件 是否安装??? 安装路径在哪???