ACM 蛇形填数

描述
在n*n方陈里填入1,2,...,n*n,要求填成蛇形。例如n=4时方陈为:
10 11 12 1
9 16 13 2
8 15 14 3
7 6 5 4
输入
直接输入方陈的维数,即n的值。(n<=100)
输出
输出结果是蛇形方陈。
样例输入
3
样例输出
7 8 1
6 9 2
5 4 3

看到这个题,首先想到的是有没有一种数学公式,可以根据行列坐标直接得出相应的值。但是思考了半天后没有结果。于是打算试一下最原始的方法,从第一个数1一直向下填,碰到边界和已经填过的位置就改变方向,方向顺序是下、左、上、右,这是一个循环,正好圈成一个正方形,继续循环,一层一层向里圈正方形,直到把所有的数都填完。

原理已经很明白了:下面是我的代码:
#include <stdio.h>
#include <stdlib.h>
//#include <windows.h>

//这里直接用int替代Point结构体就行
typedef struct _point{
    int rn;
} Point;

//方向循环
enum DIR
{
    DOWN,LEFT,UP,RIGHT
};

int main()
{
    int n, i, r, c, nr, nc;
    DIR curDir = DOWN;
    Point* curPoint;
    scanf("%d", &n);
    Point* points = (Point*)malloc(sizeof(Point) * n * n);
    nr = r = 0;
    nc = c = n - 1;
    for(i = 0; i < n * n; i++)
    {
        curPoint = &points[r*n + c];
        curPoint->rn = i + 1;

        //探测下一个点
        switch(curDir)
        {
        case DOWN:
            nr = r + 1;
            break;
        case UP:
            nr = r - 1;
            break;
        case LEFT:
            nc = c - 1;
            break;
        case RIGHT:
            nc = c + 1;
            break;
        default:
            break;
        }
        //碰到边界和已经填过的 就改变方向
        if(nr < 0 || nr >= n || nc < 0 || nc >= n || points[nr*n + nc].rn > 0)
        {
            curDir = (DIR)((int)curDir + 1);
            if((int)curDir >= 4)
                curDir = (DIR)0;
            nr = r;
            nc = c;
        }
        //根据改变的方向确定下一个位置
        switch(curDir)
        {
        case DOWN:
            r++;
            break;
        case UP:
            r--;
            break;
        case LEFT:
            c--;
            break;
        case RIGHT:
            c++;
            break;
        default:
            break;
        }
    }
    //输出
    for(i = 0; i < n * n; i++)
    {
        curPoint = &points[i];
        printf("%3d ", curPoint->rn);
        if((i+1) % n == 0)
            printf("\n");
    }
    free(points);
    //system("pause");
    return 0;
}

查看了下往上的其他代码,大体上都是这种原理,不同的就是代码实现上的差异了(不过还是感觉我的代码比较符合正常人的思维:-D)

贴上其他人的代码:

#include <cstdio>
#include <cstring>
#define MAXN 10
int a[MAXN][MAXN];
int main()
{
    int n, x, y, val=0;
    scanf("%d",&n);
    memset(a,0,sizeof(a));// clear array
    val=a[x=0][y=n-1]=1;// set the first element
    while (val<n*n)
    {
        while (x+1<n && !a[x+1][y])   a[++x][y]=++val;
        while (y-1>=0 && !a[x][y-1])  a[x][--y]=++val;
        while (x-1>=0 && !a[x-1][y])  a[--x][y]=++val;
        while (y+1<n && !a[x][y+1])   a[x][++y]=++val;
    }
    for (x=0; x<n; ++x)
    {
        for (y=0; y<n; ++y)
        {
            printf("%3d",a[x][y]);
        }
        printf("\n");
    }
    return 0;
}

目前网上最好的解法,相对比较难以理解:

#include<stdio.h>
int main()
{
    int a,b,c,d,n,sum=1;
    int yi[101][101];
    scanf("%d",&n);
    for(a=0;a<=(n-1)/2;a++)
    {
        for(b=a;b<=n-a-1;b++)
            yi[b][n-a-1]=sum++;
        for(b=n-2-a;b>=a;b--)
            yi[n-a-1][b]=sum++;
        for(b=n-a-2;b>=a;b--)
            yi[b][a]=sum++;
        for(b=a+1;b<n-a-1;b++)
            yi[a][b]=sum++;
    }
    for(c=0;c<n;c++)
    {
        for(d=0;d<n;d++)
            printf("%d ",yi[c][d]);
        printf("\n");
    }
}        

时间: 2024-08-05 19:36:49

ACM 蛇形填数的相关文章

梦工厂实验室 蛇形填数 dfs

问题 D: 蛇形填数 时间限制: 3 Sec  内存限制: 64 MB提交: 28  解决: 5[提交][状态][讨论版] 题目描述 在n*n方阵里填入1,2,...,n*n,要求填成蛇形.例如n=4时方阵为:10 11 12 19 16 13 28 15 14 37 6 5 4 输入 直接输入方阵的维数,即n的值.(n<=100) 输出 输出结果是蛇形方阵. 样例输入 3 样例输出 7 8 1 6 9 2 5 4 3 一类题型.四个方向dfs,当走不通时,t++改变方向,否则一直往一个方向走.

【基础题】蛇形填数

题目描述 在n*n方陈里填入1,2,...,n*n,要求填成蛇形.例如n=4时方陈为: 10 11 12 1 9 16 13 2 8 15 14 3 7 6 5 4 输入 直接输入方阵的维数,即n的值.(n<=100) 输出 输出结果是蛇形方陈. 样例输入 3 样例输出 7 8 1 6 9 2 5 4 3 先说一下我的思路,我把n=4时的情况列了出来,发现了奇数时,j变化,偶数时,i变化等变化规律,后来我发现需要总结很多变化规律才能算数来,总结出了n=4的,n=5时又不一样了,哎,头疼(小白的思

每日一练第7天:蛇形填数

蛇形填数.在n×n方阵里填入1,2,...,n×n,要求填成蛇形. 例如,n=4时方阵为: 10 11 12  1 9 16 13  2 8 15 14  3 7   6   5  4 解决此题的一个重要原则就是先判断下一个要填的位置是否满足条件,再填数.不是发现了不能填再退回来. 代码如下: 1 #include <stdio.h> 2 #include <string.h> 3 #define MAXN 100 4 int matrix[MAXN][MAXN]; 5 6 int

nyoj 33 蛇形填数

蛇形填数 时间限制:3000 ms  |            内存限制:65535 KB 难度:3 描述 在n*n方陈里填入1,2,...,n*n,要求填成蛇形.例如n=4时方陈为: 10 11 12 1 9 16 13 2 8 15 14 3 7  6  5 4 输入 直接输入方陈的维数,即n的值.(n<=100) 输出 输出结果是蛇形方陈. 样例输入 3 样例输出 7 8 1 6 9 2 5 4 3 1 #include <iostream> 2 using namespace s

python版蛇形填数

引 入 蛇形填数,一道经典有趣的算法入门题.这里用python来实现. 代码 vim snake.py #!/usr/bin/env python #-*- coding: utf-8 -*- #矩阵初始化函数 def genMatrix(rows,cols):       #用二维数组来代表矩阵     matrix = [[0 for col in range(cols)] for row in range(rows)]       for i in range(rows):        

[算法竞赛入门]蛇形填数

蛇形填数.在n×n方阵里填入1,2,-,n×n,要求填成蛇形.例如,n=4时方阵为:10 11 12 19 16 13 28 15 14 37 6 5 4上面的方阵中,多余的空格只是为了便于观察规律,不必严格输出.n≤8. [解析]这道题的解题思路主要还是在于如何模拟蛇形填数的过程. 我们给出两个概念的定义: (1)方向:该题中的方向顺序为"下-左-上-右" (2)墙:填数过程中若遇到墙,则应改变方向. [一种实现思路]注:这里我将n*n矩阵广义为n*m矩阵,令m=n. #includ

蛇形填数之斜着排

/* 题目大意:填数 解题思路:模拟填数的过程 难点详解:模拟填数的过程考虑清楚即可 关键点:如何填数,如何控制填数的次数 解题人:lingnichong 解题时间:2014/08/16    12:40 解题体会:是蛇形填数的另外一种变形 */ 奇数阶魔方 Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) Total Submission(s) : 4   Accepted Subm

NYOJ33 蛇形填数

一.原题 在n*n方阵里填入1,2,...,n*n.要求填成蛇形.例如n=4时方阵为: 10  11  12  1 9  16  13  2 8  15  14  3 7    6    5  4 (题目来源:<算法竞赛入门经典>[刘汝佳]) 二.题目源代码 #include <stdio.h> #include <string.h> #define MAXN 10 int a[MAXN][MAXN]; int main() { int n,x,y,tot=0; sca

&lt;蛇形填数&gt;--算法竞赛 入门经典(第2版)- 3.1 数组 程序3-3 蛇形填数

 蛇形填数: 在n×n方阵里填入1,2,....,n×n,要求填成蛇形.例如,n = 4 时方阵为:   10  11  12  1   9  16  13  2 8  15  14  3 7   6    5   4 上面的方阵中,多余的空格只是为了便于观察规律,不必严格输出.n <= 8 . 类比上面这种数学中的矩阵,我们可以考虑使用一个二维数组来储存. 解题思路:从右上角开始往下填数,当到底的时候转向左填值,当到左边的边的时候转向上填数,当到最上面的时候转向右填值...依次类推.第一轮转圈