趣味编程 - 蛇形数

所谓蛇形数其实一种泛指的说法,只要把数字按顺序读下去能够像一条蛇一样盘旋曲折,就可以理解成蛇形数.

目前我接触到的有两种:

1. 休息中的蛇(盘在一起)惊恐

首先分析一下解题思路,

首先第一个位置一定是1,从第一个位置开始,往下或者往右其实都可以,以往下为例,则横坐标一直加到不能再加为止,然后往右走,走到不能再右,然后往上,再往左.

接下来就是一个循环了.

那么如何判断无法继续走呢.以本图为例,这是一个5 * 5的矩阵,自然就有25个数字,所以很容易判断出,行列均为5.

下面给出实现代码(方向上有点差异)

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int snake[20][20] = {0};

int main(int argc, char **argv)
{
    int n = 4;

    int i = 1;
    int r = 0;
    int c = n - 1;

    snake[r][c] = i;
    while (i < n * n)
    {
        while (r + 1 < n && snake[r + 1][c] == 0)
        {
            snake[++r][c] = ++i;
        }

        while (c - 1 >= 0 && snake[r][c - 1] == 0)
        {
            snake[r][--c] = ++i;
        }

        while (r - 1 >= 0 && snake[r - 1][c] == 0)
        {
            snake[--r][c] = ++i;
        }

        while (c + 1 < n && snake[r][c + 1] == 0)
        {
            snake[r][++c] = ++i;
        }
    }

    int j = 0;
    for (i = 0; i < n; i++)
    {
        for (j = 0; j < n; j++)
        {
            printf("%d\t", snake[i][j]);
        }
        printf("\n");
    }

    return 0;
}

2. 行进中的蛇.


分析一下这条蛇:

我们可以发现,可以把这个蛇分层考虑.第一层是1, 第二层是2,3,然后是第三层...如果再拆分一下坐标或许看得更清楚一些:

0,0 ---> 1

1,0 ---> 2

0,1 ---> 3

0,2 ---> 4

1,1 ---> 5

2,0 ---> 6

那么可以分析得出,没一层加起来的和不超过层数.

下面给出实现代码:

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int snake[20][20];

int main(int argc, char **argv)
{
    int i = 0;
    int j = 0;
    int k = 1;

    int dir = 0;
    int max = 8;   // 这个值尽量给n*(n+1) / 2
    int n = 0;

    snake[i][j] = k;
    j++;
    n++;

    while (k <= 8 * 8)
    {
        if (dir == 1)
        {
            while (j <= n)
            {
                snake[i][j] = ++k;

                j++;
                if (i == 0)
                {
                    break;
                }
                i--;
            }

            n++;
            dir = !dir;
        }
        else
        {
            while (i <= n)
            {
                snake[i][j] = ++k;
                i++;

                if (j == 0)
                {
                    break;
                }
                j--;
            }

            n++;
            dir = !dir;
        }
    }

    for (i = 0; i < 20; i++)
    {
        for (j = 0; j < 20; j++)
        {
            printf("%d\t", snake[i][j]);
        }
        printf("\n");
    }

    return 0;
}

细想一下,这玩意就跟小学初中的时候,没事老师就拿出几道奥数题来锻炼我们.可能难度并不大,但是对于思路的确可以起到一定的拓展作用.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值