输入两个整数 nn 和 mm,输出一个 nn 行 mm 列的矩阵,将数字 11 到 n×mn×m 按照回字蛇形填充至矩阵中。
具体矩阵形式可参考样例。
输入格式
输入共一行,包含两个整数 nn 和 mm。
输出格式
输出满足要求的矩阵。
矩阵占 nn 行,每行包含 mm 个空格隔开的整数。
数据范围
1≤n,m≤1001≤n,m≤100
输入样例:
3 3
输出样例:
1 2 3 8 9 4 7 6 5
如图所示,蛇形数组就是回字形循环的矩阵,需解决的问题就是如何循环以及循环终止的条件,循环终止的条件挺好找的,
也就是循环到最后一个数字,即m*n处;
如何循环则有多种方法,
以下给出两种方法,硬性循环和设置偏移量。
#include<iostream>
#include<cstring>
using namespace std;
const int N =101;
int a[N][N];
int main()
{int n,m;
cin >>n>>m;
memset(a,0,sizeof(a));//数组置为全零
int ant = 1;
int x=0,y=0;//坐标
a[x][y] = 1;
while(ant<m*n)//终止条件
{
while(y<m-1&&!a[x][y+1]) a[x][++y] = ++ant;//行列结束条件,后面是++y,所以y要小于m-1
while(x<n-1&&!a[x+1][y]) a[++x][y] = ++ant;//回字形走向
while(y>0&&!a[x][y-1]) a[x][--y] = ++ant;
while(x>0&&!a[x-1][y]) a[--x][y] = ++ant;
}
for(int i =0;i<n;i++)//循环输出数组
{
for(int j =0;j<m;j++)
{
cout<<a[i][j]<<" ";
}
cout<<endl;
}
}
下面方法用到偏移量可能更容易理解,偏移量即每走一格x,y变化情况,比如向左走一格,横坐标+1,纵坐标不变,对应即x不变,y+1,同理向下,向右,向上。
#include<iostream>
using namespace std;
int res[100][100];
int main()
{
int n,m;
cin>>n>>m;
int dx[] = {0,1,0,-1},dy[]= {1,0,-1,0};//偏移量
for(int x=0,y =0,d= 0,k=1;k<=m*n;k++)//d为偏移量的变化
{
res[x][y] = k;//每格的值
int a = x +dx[d],b = y+dy[d];//a,b 为实际坐标
if(a<0||a>=n||b<0||b>=m||res[a][b])//偏移量变化的条件,越界或者不存在
{
d = (d+1)%4;
a = x+dx[d],b = y+dy[d];
}
x = a,y =b;
}
for(int i =0;i<n;i++)
{
for(int j =0;j<m;j++)
{
cout<<res[i][j]<<' ';
}
cout<<endl;
}
}
注意,小细节,此处定义res[100][100]需定义在main外,写里面会因为越界而报错,因为在不同位置,操作系统会分配不同的区域来运行代码。
首先介绍栈和堆:
栈 : 空间小 有名字的 ,例如int x = 1,的x就是分配在栈区的变量 由操作系统开辟和回收
堆 : 空间大,无名字的 由程序员开辟回收,可以new一个数组,也叫用指针指向堆空间,让无名字的堆空间内存变成有名字的 例如malloc函数。释放需要调用free函数。
再介绍 数据区和代码区:
数据区: 一般存放全局变量或者静态变量,如放在main外的或者const类型定义的。空间大
代码区: 存放运行代码的地方
故如果是比较大的数组,要么放在数据区,要么new一个对象放在堆区,放在栈里会因为越界超限而报错。