题目 1097: 蛇行矩阵
时间限制: 1Sec 内存限制: 64MB 提交: 12964 解决: 8659
题目描述
蛇形矩阵是由1开始的自然数依次排列成的一个矩阵上三角形。
输入
本题有多组数据,每组数据由一个正整数N组成。(N不大于100)
输出
对于每一组数据,输出一个N行的蛇形矩阵。两组输出之间不要额外的空行。矩阵三角中同一行的数字用一个空格分开。行尾不要多余的空格。
样例输入
5
样例输出
1 3 6 10 15 2 5 9 14 4 8 13 7 12 11
第一种方法是我自己想出来的方法,有点垃圾,但是建议也看一下,多一个思路总是好的
就用样例看,将这个斜着看,输入为n时,发现一共有n行,并且第n行有n个数,并且从上往下看,从左向右看,发现正好是自然数的顺序,按这个样例来说,是从1数到15;
我的想法就是,用一个二维数组将此数据存储,通过改变i和j的值,对此二维数组依次赋值;
赋值顺序就是第一张图中的那样,我这里i和j都不取0,都是从1开始,方便观察;
则赋值顺序为a[1][1],a[2][1],a[1][2],a[3][1],a[2][2],a[1][3],a[4][1],a[3][2],a[2][3],a[1][4],a[5][1],a[4][2],a[3][3],a[2][4],a[5][1];
不难发现,每次赋值到第一行后,就会去赋值第一列,这里用k表示在第几行(斜着看),则这里用代码表示为if(j==k) {i=k+1; j=1; k++; } (此时的J==k,就表示赋值到第一行了,可以演算纸上写一下,很容易就看出来了)
而除了这个情况之外,会发现,下一次赋值的i会-1,j会+1,用代码表示为else{ i--; j++; }
而要赋的值大小为多少呢,这个很容易就能发现,前面说了,是由1数到15,则要赋的值每一次加一,我这里将其表示为 m++;(m为要赋的值)
至于最后,要将此矩阵输出,要考虑一个问题,因为正常矩阵输出是一个正方形,但是这里的输出是三角形,所以需要考虑怎么输出,我是使变量m=n;每循环一次就执行m--,使j<=m;则每行输出的数量每次少一个,可以满足输出三角形。
#include<iostream> //蛇形矩阵 1
using namespace std;
int main()
{
int n,m,i,j,a[101][101];
while(cin>>n)
{
i=1;j=1;m=1;
int k=1;
for(int p=1;p<=k;p++) //每一斜排
{
a[i][j]=m;
m++;
if(j==k)
{
i=k+1;
j=1;
k++;
p=0;
//cout<<"i:"<<i<<" "<<"j:"<<j<<endl; //用于观察 调试
}
else
{
i--;
j++;
//cout<<"i:"<<i<<" "<<"j:"<<j<<" "; //用于观察 调试
}
if(j==n) break; //赋值到最后,用来跳出;
}
a[1][j]=m;
m=n;
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
if(j==m)
cout<<a[i][j]<<endl;
else
cout<<a[i][j]<<" ";
}
m--;
}
}
return 0;
}
第二个方法是我的同学想出来的,按这个方法讲,本来为(1),将每一列的数向上提之后,变成了(2)
1
2 3
4 5 6
7 8 9 10
11 12 13 14 15 (1)
向上提之后变成
1 3 6 10 15
2 5 9 14
4 8 13
7 12
11 (2) 从(1)变成(2)也是只需要注意i和j之间的变化即可
#include<iostream> //2 向上提
using namespace std;
int main()
{
int a[101][101],n,i,j,k,m=1;
cin>>n;
for(i=1;i<=n;i++)
{
for(j=1;j<=i;j++)
{
a[i][j]=m;
m++;
}
}
m=n;
for(j=1;j<=n;j++)
{
k=j-1;
for(i=1;i<=m;i++)
{
if(j==1)
break;
a[i][j]=a[i+k][j];
if(i==m)break;
}
m--;
}
m=n;
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
if(j==m)
cout<<a[i][j]<<endl;
else
cout<<a[i][j]<<" ";
}
m--;
}
return 0;
}
最后还有一种方法,应该是网上最好的方法,很多人都是用这个方法,这个方法就是发现了蛇形矩阵的规律,而得出公式后写的代码;
#include <stdio.h>
//N为总行数,rows为第几行,打印该行数据
void printN(int N, int rows)
{
//确定第rows行的第一个元素的值:a(n) = a(n-1) + n - 1; a1 = 1;
int first = 1;
int i;
for (i = 1; i <= rows; i++)
{
first += i - 1;
}
//第rows行的第一个元素为first
int tmp = first;
//第rows行的元素之间的增量inc从rows+1开始
int inc = rows + 1;
for (i = 1; i <= N - rows + 1; i++) //输出第rows行的元素,共有N-rows+1个
{
//输出元素时,该行最后一个元素后面没有空格符
if (i < (N - rows + 1))
printf("%d ", tmp);
else
printf("%d", tmp);
tmp += inc; //每一个元素都是前一个元素加上inc
inc++; //inc++
}
}
int main()
{
int N;
scanf("%d", &N);
//输出N行数据
int i;
for (i = 1; i <= N; i++)
{
printN(N, i);
printf("\n");
}
return 0;
}