蛇形填数(总结篇)

最近在刷蓝桥杯真题时,又做到了曾经我们做过的“蛇形填数”,只不过上次我们做过的是螺旋形的,而这次我们遇到的是三角形的,如下:

该题是一道填空题,我一开始的想法主要是想按照“三角形螺旋规则”将数字都填入一个二维数组,最后查找这个数组内的第20行第20列的元素是什么来解决问题

不过后来发现这样做有些麻烦,毕竟这是一道填空题

也是做着做着发现了规律,我们依次把第一行第一列、第二行第二列、第三行第三列————的数字列出来————1、5、13、25、41

我们发现每一个数与上一个数相差的数都是4的倍数,以此为线索我发现了求第n行第n列的公式————4*(n-1)+上一个数

int ans(int n)
{
    if(n==1)
        return 1;
    else
        return ans(n-1)+4*(n-1);
}

这样我们就得到答案————761

下面我们也是整理一下我们目前所遇到的所有类型的蛇形填数

  1. S形蛇形填数

  2. 螺旋形蛇形填数

  3. 三角形蛇形填数

一、S形蛇形填数

在这里插入图片描述
这是蛇形填数中最简单的一种,我们只需要按照S形的方法填充数字即可。
我们可以发现如果我们定义一个二维数组,那么二维数组的第0列、第2列、第4列,即偶数列,数字都是从上往下依次填充的;而第1列、第3列、第5列,即奇数列,数字都是从下到上依次填充的。

 

#include<stdio.h>
int main()
{
	int n = 0;
	int arr[100][100] = { 0 };
	scanf("%d", &n);//输入需要填充的数组的大小,arr[n][n]
	//填充数组
	int i = 0;
	int num = 1;
	for (i = 0; i < n; i++)//需要打印n列数字
	{
		if (i % 2 == 0)//偶数列填充
		{
			int x = 0;
			int y = i;
			for (x = 0; x <= n-1; x++)
			{
				arr[x][y] = num;
				num++;
			}
		}
		else//奇数列填充
		{
			int x = n - 1;
			int y = i;
			for (x = n - 1; x >= 0; x--)
			{
				arr[x][y] = num;
				num++;
			}
		}
	}
	//打印数组
	int j = 0;
	for (i = 0; i < n; i++)
	{
		for (j = 0; j < n; j++)
		{
			printf("%-3d ", arr[i][j]);
		}
		printf("\n");
	}
	return 0;
}

 

二、螺旋形蛇形填数

在这里插入图片描述 

这是蛇形填数中较为复杂的一种,我们需要从数组右上角开始顺时针对数组进行填充数字。
首先,我们需要找到一个循环并找到填数的规律,然后我们确定循环的次数就可以完成填充。就像第一种S形蛇形填数一样,它的规律填数规律我们找到了,而循环的次数便是用户输入的数字n的大小。

在这里插入图片描述 

在螺旋形蛇形填数中我们可以把填满数组一圈当作为一次循环,在这一次循环中我们又分成四步进行填充,我们假设用户输入的数字为n,那么第一步就是从arr[0] [n-1]依次向下填充到arr[n-2][n-1]],第二步就是从arr[n-1][n-1]依次向左填充到arr[n-1][1],第三步就是从arr[n-1][0]依次向上填充到arr[1][0],第四步就是从arr[0][0]依次向右填充到arr[0][n-2]。
每四步为一次循环,但是当填满一圈填下一圈时,圈会变小,而每次循环的每一步的起始元素与结束元素的行列坐标也会变化,那么我们将循环次数定为i,当第一次循环时i的值为0,每次循环i的值加一,那么我们只需将循环中四个步骤的起始与结束元素的坐标适当加上或者减去i即可。即:
第一步: 从arr[i] [n-1-i]依次向下填充到arr[n-2-i][n-1-i]
第二步: 从arr[n-1-i][n-1-i]依次向左填充到arr[n-1-i][1+i]
第三步: 从arr[n-1-i][i]依次向上填充到arr[1+i][i]
第四步: 从arr[i][i]依次向右填充到arr[i][n-2-i]
而需要循环的次数便是n/2,但是当n是奇数时,你会发现数组的正中央的那个位置没有得到填充,所以如果用户输入的n为奇数,我们需要在循环填充完成后再填充那个正中央的数。

 

#include<stdio.h>
int main()
{
	int n = 0;
	int arr[100][100] = { 0 };
	scanf("%d", &n);//输入需要填充的数组的大小,arr[n][n]
	//填充数组
	int i = 0;
	int num = 1;
	for (i = 0; i < n / 2; i++)//循环的次数
	{
		int x = i;
		int y = n - 1 - i;
		for (x = i; x <= n - 2 - i; x++)//第一步,列不变,行依次++
		{
			arr[x][y] = num;
			num++;
		}
		for (y = n - 1 - i; y >= i + 1; y--)//第二步,行不变,列依次--
		{
			arr[x][y] = num;
			num++;
		}
		for (x = n - 1 - i; x >= i + 1; x--)//第三步,列不变,行依次--
		{
			arr[x][y] = num;
			num++;
		}
		for (y = i; y <= n - 2 - i; y++)//第四步,行不变,列依次++
		{
			arr[x][y] = num;
			num++;
		}
	}
	if (n % 2 != 0)//判断n是否为奇数
		arr[n / 2][n / 2] = num;//填充正中央的数
	//打印数组
	int j = 0;
	for (i = 0; i < n; i++)
	{
		for (j = 0; j < n; j++)
		{
			printf("%-3d ", arr[i][j]);
		}
		printf("\n");
	}
	return 0;
}

也可:

//蛇形填数
#include<stdio.h>
#include<string.h>
int main()
{
	int n,num[20][20],i,tol,j,x,y;
	scanf("%d",&n);
	memset(num,0,sizeof(num));
	tol=num[x=0][y=n-1]=1;
	while(tol!=n*n)
	{
		while(x+1<n&&!num[x+1][y]) num[++x][y]=++tol;
		while(y-1>=0&&!num[x][y-1]) num[x][--y]=++tol;
		while(x-1>=0&&!num[x-1][y]) num[--x][y]=++tol;
		while(y+1<n&&!num[x][y+1]) num[x][++y]=++tol;
	}
	for(i=0;i<n;i++)
	{
		for(j=0;j<n;j++)
		{
			printf("%-3d",num[i][j]);
		}
		printf("\n");
	}
	return 0;
}

 

三、三角形蛇形填数(蓝桥杯)

在这里插入图片描述 

这是蛇形填数中最复杂的一种,我们需要从左上角开始按斜S形对数组进行填数。
虽然看似复杂,但仔细观察还是有规律可循的,我们可以斜着看,将每每条斜着的一串数字看成是一次循环填充数字,循环的次数便是用户输入的n的大小。
我们依然定义i为循环次数,那么当i为0、2、4即偶数的时候,数字都是从左下向右上填充的;当i为1、3、5即奇数的时候,数字都是从右上向左下填充的。
因为循环次数i是从0开始的,所以每次循环填充的数字的个数就可以表示为i+1。
 

#include<stdio.h>
int main()
{
	int n = 0;
	int arr[100][100] = { 0 };
	scanf("%d", &n);//输入需要填充的数组的大小,arr[n][n]
	//填充数组
	int i = 0;
	int num = 1;
	for (i = 0; i < n; i++)
	{
		if (i % 2 == 0)//i为偶数时,数字从左下向右上填充
		{
			int x = i;
			int y = 0;
			while (x+1)//每次循环填充的数字个数为i+1即x+1个
			{
				arr[x][y] = num;
				num++;
				x--;
				y++;
			}
		}
		else//i为奇数时,数字从右上向左下填充
		{
			int x = 0;
			int y = i;
			while (y+1)//每次循环填充的数字个数为i+1即y+1个
			{
				arr[x][y] = num;
				num++;
				x++;
				y--;
			}
		}
	}
	//打印数组
	int j = 0;
	for (i = 0; i < n; i++)
	{
		for (j = 0; j < n; j++)
		{
			printf("%-3d ", arr[i][j]);
		}
		printf("\n");
	}
	return 0;
}

值得注意的是:代码中每次循环填充的数字个数用x+1和y+1表示,而没有用i+1是避免在循环过程中因为改变循环变量而导致循环失控。

以上笔记参考于(2条消息) 三种蛇形填数_2021dragon的博客-CSDN博客_蛇形填数

  • 11
    点赞
  • 53
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ZZZWWWFFF_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值