蛇形填数
- 描述:
给定一个 n , 在 n * n 的方阵中填入 1, 2, 3,……,n * n, 要求填成蛇形。
例如在 n = 5 时 , 如下所示:
13 14 15 16 1
12 23 24 17 2
11 22 25 18 3
10 21 20 19 4
9 8 7 6 5
-
思路解析
1.最大值为n*n;从右起分别一条直线画蛇形
流程为:取到正确数值->建立二维数组保存n行n列的值->计算得出每个行和列所该有的值->打印 -
分析:
如果我们先考虑右下左上第一行,应该时这样的;
#include <stdio.h>
#include <string.h>
#define Max 8
int main()
{
int iScanf = 0;
while (scanf_s("%d",&iScanf)==1&&iScanf>0)
{//取到正确数值
int Sank[Max][Max];
memset(Sank, 0, sizeof(Sank));//养成开辟开间和声明变量时先初始化的好习惯
int iTotal = 0;
for (int i = 0; i < iScanf - 1; i++)//给右侧最后一列赋值
{
Sank[i][iScanf - 1] = ++iTotal;
}
for (int j = iScanf - 1; j <= 0 ; j--)//给底部最后一行赋值
{
Sank[iScanf - 1][j] = ++iTotal;
}
for (int k = iScanf - 1; k <= 0; k--)//给左侧第一列赋值
{
Sank[0][k] = ++iTotal;
}
for (int l = 0; l < iScanf ; l--)//给顶部第一行赋值
{
Sank[0][l] = ++iTotal;
}
}
}
接下来会从1行n-2列开始接续按照++itotal的方式增加;所以我们需要考虑能不能结合这种方式给一个不错的循环。
经过对最后一行数值的对比,我们发现最后得到的列数l是呈规律性变化,所以我们考虑赋完第一次值后再回到赋值的地方进行再次赋值。
下面是最后的代码:可以跟着断点看看他的赋值过程:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define Max 4
int main()
{
int iScanf = 0;
while (scanf_s("%d",&iScanf)==1&&iScanf>0)
{//取到正确数值
int Sank[Max][Max];
memset(Sank, 0, sizeof(Sank));//养成开辟开间和声明变量时先初始化的好习惯
int iTotal = 0;
int iRow = 0; //行
int iRank = iScanf - 1; //列
Sank[iRow][iRank] = ++iTotal;
while(iTotal < iScanf*iScanf) //不能等于,会多执行一次
{
while(iRow + 1 < iScanf && !Sank[iRow+1][iRank])//给右侧赋值
//!Sank[iRow - 1][iRank]代表这个位置没有被填过,仍然为0
//不能直接--的原因是后面需要--;
{
Sank[++iRow][iRank] = ++iTotal;
}
while (iRank - 1 >= 0 && !Sank[iRow][iRank-1])//给底部赋值
{
Sank[iRow][--iRank] = ++iTotal;
}
while (iRow - 1 >= 0 && !Sank[iRow-1][iRank])//给左侧赋值
{
Sank[--iRow][iRank] = ++iTotal;
}
while (iRank + 1<iScanf && !Sank[iRow ][iRank+1])//给顶部赋值
{
Sank[iRow][++iRank] = ++iTotal;
}
}
for (int iLine = 0; iLine < iScanf; iLine++)
{
for (int iColunm = 0; iColunm < iScanf; iColunm++)
{
printf_s("%3d", Sank[iLine][iColunm]);
}
printf_s("\n");
}
}
system("Pause");
return 0;
}