算法入门-第三章:数组和字符串-蛇形填数

本文介绍了如何解决蛇形填数问题,从题目描述到解题思路,详细阐述了如何构建二维数组并按照蛇形路径填充数字。在过程中,强调了判断与移动的策略,同时提及了短路运算符在代码中的应用。
摘要由CSDN通过智能技术生成

背景

从现在开始准备写一个关于我学习《算法竞赛-入门经典》学到的一些知识点的系列博客。

蛇形填数

题目描述

题目描述:
给定一个 n , 在 n * n 的方阵中填入 1 ,2, 3,……,n * n, 要求填成蛇形。
例如在 n = 5 时 , 如下所示:
13 14 15 16 1
12 23 24 17 2
11 22 25 18 3
10 21 20 19 4
9 8 7 6 5

思路:

  1. 首先构造操作环境:声明一个足够大的二维数组:a[maxn][maxm]
  2. 蛇形填数,顾名思义就是像蛇的形状一样对数组进行填数,理解成从“1”依次开始。设“笔”的坐标是(x,y)则一开始的坐标是x=0,y=n-1即(0,n-1);“笔”的移动轨迹就是“下 下 下……左 左 左……上 上 上……右 右 右……”,就是先朝着一个方向走,直到不能走了(这里是有条件的),再换个方向继续走。
    不能走有两种情况
    2.1: 到达蛇形填数形成矩阵的边界了,再继续走就越界了(即使数组没越界)。举个例子,比如题目中给定了初始数字n=5,那么从1开始往下走,走到5就不能继续往下写6(如果继续往下写6,就不能构成一个55的蛇形矩阵了),即使数组声明的是1010的数组空间。
    2.2:继续走就要走到已经填过的格子了;再拿本题题目中给的例子,比如从16往下走,填到19就不能继续往下走了,往下走就是已经填过的6了。

题目总结:

范例代码:(main函数部分)

int main(){
   int n,x,y,tot=0;
   scanf("%d",&n);
   memset(a,0,sizeof(a));//数组清零 
   tot=a[x=0][y=n-1]=1;
   while(tot<n*n){
   	while(x+1<n && !a[x+1][y]) a[++x][y]=++tot;//从最后一列往下走 
   	while(y-1>=0 && !a[x][y-1]) a[x][--y]=++tot;//从最后一行往右走 
   	while(x-1>=0 && !a[x-1][y]) a[--x][y]=++tot;//从第一列往上走		
   	while(y+1<n && !a[x][y+1]) a[x][++y]=++tot;//从第一行往右走 
   }
   //打印输出 
   for(x=0;x<n;x++){
   for(y=0;y<n;y++)
   printf("%3d",a[x][y]);
   printf("\n");
} 
反思及总结

主要的原则是:先判断再移动
拿内层的一个while循环来说:
while(x+1<n && !a[x+1][y]) a[++x][y]=++tot;//从最后一列往下走
先判断x+1<n 且 !a[x+1][y] ,先做预判,即是否越界,针对了以上所说的两种不能走的情况。

拓展一个知识点

“&&” 是短路运算符,什么意思呢?
while(x+1<n && !a[x+1][y]) a[++x][y]=++tot;//从最后一列往下走 这行代码中如果x+1<n为假,就不会计算 !a[x+1][y],因此,不用担心当x+1<n为假时,会造成 !a[x+1][y]的访问非法内存问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值