#include<stdio.h>

int main() { int n = 0; scanf("%d", &n); int mtr[1001][1001];//矩阵,不用变长数组省事一点(不用担心越界) int limit = 2;//方形边界边长 int row = 0;//目前所在元素的行下标 int col = 0;//目前所在元素的列下标 int dir = 0;//0代表斜向下方向,1表示斜向上方向 int num = 2;//要放入的值,初始为2,因为第一个提前放入 int state = 0;//表示上半部分(0)还是下半部分(1) mtr[0][0] = 1;//初始化第一个元素 mtr[n-1][n-1] = n*n;//初始化最后一个元素 int delta = 1;//limit增量,为正数时说明元素还在上半部分,为负数时说明元素在下半部分 int i = 0;//循环变量 int j = 0;//循环变量

while(num < n * n - 1)//记得-1,因为把最后一个元素提前放入了
{
    if(!dir)//斜向下
    {
        if(!state)//元素在上半部分时
        {
            mtr[row][++col] = num++;//右移
            while(col > 0 && row < limit)
            {
                //阶梯式斜向下移
                mtr[++row][--col] = num++;
            }                
        } 
        else//元素在下半部分时
        {
            mtr[++row][col] = num++;//下移
            while(col > n - limit && row < n)
            {
                //阶梯式斜向下移
                mtr[++row][--col] = num++;
            }                 
        }
            
    }
    else//斜向上
    {
        if(!state)//元素在上半部分时
        {
             mtr[++row][col] = num++;//下移
            while(row > 0 && col < limit)
            {
                //阶梯式斜向上移
                mtr[--row][++col] = num++;
            }                 
        }   
        else//元素在下半部分时
        {
            mtr[row][++col] = num++;//右移
            while(row > n - limit && col < n)
            {
                //阶梯式斜向上移
                mtr[--row][++col] = num++;
            }                 
        }
            
    }
    if(limit == n)//方形边界达到最大了,开始变小
    {
        delta = -delta;
        state = 1;//开始下半部分了
    }
    limit += delta;//方形边界变化(变大或变小)
    dir = !dir;//方向反转
}

for(i = 0; i < n; i++)//打印元素
{
    for(j = 0; j < n; j++)
    {
        printf("%d ", mtr[i][j]);
    }
    printf("\n");
}

return 0;

}