Exercise(20):蛇形填数

/* 张理想 蛇形填数 描述 在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 问题分析: 以下为递归解决: 为了方便计算,将方阵大小设置为map[n+2][n+2],并将四周设置为-1,中部待填数的区域设为0 由栗子可知,从右上角开始填数. 递归填数,当遇到边界(-1)便更换方向. 注意:本题亮点在于方向的变换. 为了处理方向变更的问题,设置一个参数direct表示当前方向0,1,2,3分别表示下左上右. (1)当direct == 0时,向下填数并判断下一个位置 if( 碰到边界 Or 已经填了数字 ): 是,则将方向改为向左(direct == 1)并向左填数. 否,则继续沿着原方向填数. (2)当direct == 1时,向左填数并判断下一个位置 if( 碰到边界 Or 已经填了数字 ): 是,则将方向改为向上(direct == 2)并向上填数. 否,则继续沿着原方向填数. (1)当direct == 2时,向上填数并判断下一个位置 if( 碰到边界 Or 已经填了数字 ): 是,则将方向改为向右(direct == 3)并向右填数. 否,则继续沿着原方向填数. (1)当direct == 3时,向右填数并判断下一个位置 if( 碰到边界 Or 已经填了数字 ): 是,则将方向改为向下(direct == 0)并向下填数. 否,则继续沿着原方向填数. 代码实现如下... */
#include <iostream>
using std::cin;
using std::cout;
using std::ends;
using std::endl;
int n;              // 方阵规格 
bool flag;          // 判断是否填满 
int cc = 0;         // 填写的数 
int map[102][102];  // 方阵 (为了方便计算,添加额外的4条边界)

void Init()                         // 初始化方阵 
{
    int i,j;
    for(i=0;i<n+2;i++)          
    {
        for(j=0;j<n+2;j++)
        {
            if(i==0 || i==n+1)      // 为了方便计算 方阵的最顶行、最底行、最左列、最右列皆设为-1
                map[i][j] = -1;
            else if(j==0 || j==n+1)
                map[i][j] = -1;
            else 
                map[i][j] = 0;
        }
    }
}

void Handle(int x,int y,int direct) // 在阵内填数 x,y分别代表横纵坐标 
{                                   // direct代表当前填数的方向 0,1,2,3 分别表示下左上右 
    if(cc == (n*n))                 // 当计数器达到n*n时,填数完毕 
    {
        flag = true;
        return;
    }

    map[x][y] = ++cc;                   // 填数 

    if(!flag)
    {
        if(direct == 0)                     
        {
            if(map[x+1][y] == 0)        // 向下
                Handle(x+1,y,direct);
            else                        // 碰到边界 Or 已经填了数字 
            {   
                direct = 1;             // 变向:向左 
                Handle(x,y-1,direct);
            }
        }
        else if(direct == 1)            
        {
            if(map[x][y-1] == 0)        // 向左 
                Handle(x,y-1,direct);
            else                        // 碰到边界 Or 已经填了数字
            {
                direct = 2;             // 变向:向上 
                Handle(x-1,y,direct);
            }
        }   
        else if(direct == 2)
        {
            if(map[x-1][y] == 0)        // 向上 
                Handle(x-1,y,direct);
            else                        // 碰到边界 Or 已经填了数字
            {
                direct = 3;             // 变向:向右 
                Handle(x,y+1,direct);
            }
        }
        else if(direct == 3)
        {
            if(map[x][y+1] == 0)        // 向右 
                Handle(x,y+1,direct);
            else                        // 碰到边界 Or 已经填了数字
            {
                direct = 0;             // 变向:向下 
                Handle(x+1,y,direct);
            }
        }
    }
}

void Show()                         // 打印方阵 
{
    int i,j;
    for(i=1;i<=n;i++)
    {
        for(j=1;j<=n;j++)
        {
            cout<<map[i][j]<<ends;
        }
        cout<<endl;
    }
}

int main()
{
    cin>>n;
    if(n<0 || n>100) return -1;

    Init();             // 初始化方阵
    Handle(1,n,0);      // 在阵内填数 
    Show();             // 打印方阵 

    return 0;
}

你可能感兴趣的:(蓝桥)