Ⅰ.运用方向数组(易)

所谓方向数组,即为设置一个一维数组→数组内包含0,1,-1,用于改变被赋值数组的处理方向

典例:螺旋矩阵

以下为 ①行改变方向数组 dx[4]={0,1,0,-1}

②列改变方向数组 dy[4]={-1,0,1,0}

③被赋值数组 a[x][y]

如何使用方向数组改变数组的处理方向呢?

比如:

#include <stdio.h>int main()
{int x = 0, y = 0, k = 1;char a[1000][1000] = { 0 };int dx[4] = { 0,1,0,-1 };int dy[4] = { -1,0,1,0 };int n, i, j;scanf("%d", &n);for (i = 0; i < n * n; i++){a[x][y] = 'A' + i % 26; //数组赋值等等x += dx[k], y += dy[k];if (x < 0 || y < 0 || x >= n || y >= n || a[x][y] != 0) //越界与碰壁{x -= dx[k];y -= dy[k];k = (k + 1) % 4;  //改变处理方向(改变引用方向数组元素的位置)x += dx[k];y += dy[k];}}for (i = 0; i < n; i++){for (j = 0; j < n; j++) printf("%c", a[i][j]);printf("\n");}}

越界:即为超出数组在题目中n行n列的范围

碰壁:在处理数组元素的时候,又一次碰到之前处理过的元素

我们以n=4为例,(x,y)x表示数组的行,y表示列来演示越界与碰壁

过程为:

x+=dx[k],y+=dy[k];其中k的初始值为1

则(0.0)→ (1.0) →(2.0)→ (3.0) →(4.0)【越界】

进入if语句:(4.0)→(3.0) k=2;此时dx[k]=0,dy[k]=1

(3.0)→(3.1)→(3.2)→(3.3)→(3.4)【越界】

进入if语句:(3.4)→(3.3) k=3;此时dx[k]=-1,dy[k]=0

(3.3)→(2.3)→(1.3)→(0.3)→(-1.3)【越界】

进入if语句:(-1.3)→(0.3)k=(3+1)%4=10;此时dx[k]=0,dy[k]=-1

(0.3)→(0.2)→(0.1)→(0.0)【碰壁】

进入if语句............

并以此类推

经过方向数组的运用,我们可以通过仅仅改变方向数组的内容,来实现对螺旋矩阵不同方向的处理

无论是逆时针,还是顺时针,或者是改变起始位置的情况下,运用方向数组都可以更加轻松的完成

上方的代码是以a[0][0]为起始,起始处理方向为:向下↓ 进行的逆时针赋值

若我们要将起始处理方向改为:向右→ 进行顺时针赋值

则将方向数组改变为

int dx[4] = { -1,0,1,0 };

int dy[4] = { 0,1,0,-1 };即可

Ⅱ.写出4个方向的赋值过程并且组成循环

概念介绍:

①循环不变量:指对于循环处理,其规律应该相同,防止出现溢出等等情况

②偏移量offset:每一次完整循环,条件数值上带来的偏移

③循环不变原则:每一次进入循环,都要保持处理规律不变

对于螺旋矩阵的规律,我们要用

〇 → 的形式 进行 一圈式的赋值循环

↑      ↓

为了创造出此类图案,并且赋值,我们需要用到二维数组

关于二维数组我们要了解 a[x][y]中x表示行,y表示列

在C语言中二维数组是按照行来存放的 意思就是说 一行放y列,一共x行

也就是 y1 y2 y3 y4 y5

x1{ 1 , 2 , 3 , 4 , 5 }

x2{ 6 , 7 , 8 , 9 , 10 }

所以对于a[x][y]的赋值,就应该一行赋完再换行→意味着a[x][y]的循环应该是y++赋值

for (; y < sty + n - offset; y++) a[x][y] = num++;

不过对着列赋值同样也是可以的

for (; x < stx + n - offset; x++) a[x][y] = num++;

针对循环不变原则,当我们要处理每一条边的时候,都要保持处理规律不变

那么处理模式就可以是 左闭右开 [....) 或者 右闭左开(...]

即 处理一边上的数组元素,但不处理作为下一边开头的数组元素

0→ 1→丨(阻断) 2 这样每一条边如此处理,当完成4边的时候正好形成一个闭环

对于偏移量的模糊了解是致命的:起点〇→→offset丨→n 每完成一圈,左右上下边界减小,整体向内缩小一个单位

若按照单个边来算,一条边缩进2个单位,所以每次结束一圈的循环,offset+=2;其中offset的默认值要为1

所以 前两边的循环条件就有:y我们假定n=3,starty=0则 yy

所以对于无法赋值的奇数情况下的中间值

我们则要单独进行赋值a[mid][mid]=num++;

标准做法

#include <stdio.h>
int main() {
char ans[1000][1000];
int n;
scanf_s("%d", &n);
int i, j;
//设置每次循环的起始位置
int startX = 0;
int startY = 0;
//设置二维数组的中间值,若n为奇数。需要最后在中间填入数字
int mid = n / 2;
//循环圈数
int loop = n / 2;
//偏移数
int offset = 1;
//当前要添加的元素
int count = 0,num=90;while (loop) {i = startX;j = startY;//模拟上侧从左到右for (; j < startY + n - offset; j++) {ans[startX][j] = num-(count++)%26;}//模拟右侧从上到下for (; i < startX + n - offset; i++) {ans[i][j] = num - (count++) % 26;}//模拟下侧从右到左for (; j > startY; j--) {ans[i][j] = num - (count++) % 26;}//模拟左侧从下到上for (; i > startX; i--) {ans[i][j] = num - (count++) % 26;}//偏移值每次加2offset += 2;//遍历起始位置每次+1startX++;startY++;loop--;}//若n为奇数需要单独给矩阵中间赋值if (n % 2)ans[mid][mid] = num - (count++) % 26;for(i = 0; i < n; i++) {for (j = 0; j < n; j++) printf(" %c", ans[i][j]);printf("\n");}
}

螺旋矩阵/旋转摆花的两种做法(含方向数组)相关推荐

  1. SPOJ 1812 LCS2 - Longest Common Substring II (后缀自动机)【两种做法】

    SPOJ 1812 LCS2 - Longest Common Substring II (后缀自动机)[两种做法] 手动博客搬家: 本文发表于20181217 23:54:35, 原地址https: ...

  2. android旋转动画的两种实现方式

    在android开发,我们会常常使用到旋转动画,普通情况下旋转动画有两种实现方式,一种是直接通过java代码去实现,第二种是通过配置文件实现动画.以下是两种动画的基本是用法: 纯Java代码实现: / ...

  3. sql server数据集中取第一条记录及保留几位小数的两种做法及前n行写法

    1.使用top(1) eg: select top(1) num,Name from M_Student where name = 'xy' 前n行可使用top https://blog.csdn.n ...

  4. CCIE理论-第十三篇-IPV6-路由-静态+(EIGRP+OSPF)两种做法+IPV4-ARP代理详解(精髓篇)

    CCIE理论-第十三篇-IPV6-路由-静态+(EIGRP+OSPF)两种做法+IPV4-ARP代理详解(精髓篇) 其实呢,路由协议,静态路由 他还是ipv4那一套,只不过多了点东西 该怎么搞怎么搞, ...

  5. 正则 8-18位长度,数字,字母,字符 任意两种,不含中文测试通过

    原文:正则 8-18位长度,数字,字母,字符 任意两种,不含中文测试通过 String regex = "^(?!^(\\d+|[a-zA-Z]+|[~!@#$%^&*?]+)$)^ ...

  6. 7-1 寻找大富翁 (25 分)(思路加详解+两种做法(一种优先队列,一种vector容器))

    一:题目 胡润研究院的调查显示,截至2017年底,中国个人资产超过1亿元的高净值人群达15万人.假设给出N个人的个人资产值,请快速找出资产排前M位的大富翁. 输入格式: 输入首先给出两个正整数N(≤1 ...

  7. 7-32 哥尼斯堡的“七桥问题” (25 分)(思路+详解+题目分析)两种做法任选其一

    一:题目: 哥尼斯堡是位于普累格河上的一座城市,它包含两个岛屿及连接它们的七座桥,如下图所示. 可否走过这样的七座桥,而且每桥只走过一次?瑞士数学家欧拉(Leonhard Euler,1707-178 ...

  8. Python关于人脸图片转换128/512维度向量的两种做法

    近期工作需要调研关于人脸转换向量存储到自家的数据库去做人脸识别,所以我在网上pick了两种关于人脸转换向量的两种简单做法,但是作为一个java开发工程师,对python的使用不是很精通,所以代码仅供参 ...

  9. bzoj5042: LWD的分科岛 两种做法

    Description 大家都知道在文理分科的时候总是让人纠结的,纠结的当然不只是自己.比如 YSY 就去读了文科, LWD 知道了很 气.于是他就去卡了 BZOJ 测评机, 晚上他做了一个谜一样的梦 ...

最新文章

  1. iis7下站点日志默认位置
  2. php中访问控制关键字,PHP 关于访问控制和运算符优先级简介
  3. 深入Activity的作业完成
  4. python 统计使用技巧
  5. PowerDesigner的数据类型
  6. selinux会阻碍挂载嘛_为什么追求完美可能会阻碍您成为新手Web开发人员
  7. LeetCode 1015. 可被 K 整除的最小整数(数学)
  8. Maven学习(五)————依赖的特性辨析
  9. java arraylist排序_一文读懂Java集合框架
  10. pandas 时间序列分析(一)—— 基础
  11. 136.Single Number
  12. MatLab 2016b下载资源
  13. opencv cvtcolor函数中断异常
  14. win10系统电脑提示此程序被组策略阻止的解决办法
  15. 共享计算机桌面需要密码,win10局域网共享文件需要输密码怎么办?_win10访问共享文件需要密码的解决办法-爱纯净...
  16. RxJava详细解析
  17. NLP文本相似度(TF-IDF)
  18. 2022(招聘季)linux面试高频题
  19. 解决overleaf打不开(reCaptcha失效)问题
  20. 教你如何找回被盗的QQ密码(转贴)

热门文章

  1. 护肤:食盐美容4招 控油除痘去黑头 - 生活至上,美容至尚!
  2. 爬虫准备 - 认识HTMLcss
  3. 恩智浦NXP RT1062F 本地神经网络人脸识别接口 - [详解]
  4. 书中的阿甘和电影中的阿甘
  5. LLVM每日谈之二十八 I am leaving llvm
  6. weka中ID3算法及可视化
  7. 使用组策略配置Windows防火墙设置和规则
  8. 期货我用十年(坚持做期货十年的人)
  9. 加快Android模拟器运行速度
  10. java创建数组的两种方法