蛇形矩阵,蛇形填数(两种模拟写法,好理解)
输入两个整数n和m,输出一个n行m列的矩阵,将数字 1 到 n*m 按照回字蛇形填充至矩阵中。
具体矩阵形式可参考样例。
输入格式
输入共一行,包含两个整数n和m。
输出格式
输出满足要求的矩阵。
矩阵占n行,每行包含m个空格隔开的整数。
数据范围
1≤n,m≤100
输入样例:
3 3
输出样例:
1 2 3
8 9 4
7 6 5
这是一道非常经典的题,就是模拟填数过程将数按照他所规定的方法填进去,
写法一:教科书式写法;
首先把第一个数填上去,然后根据填入规则再依次遍历填空,这样写的好处是十分快捷,但是当循环出现错误的时候就会出不来,需要debug的耐心
int n,m;
cin>>n>>m;
int ans=1;//首先把第一个数填好,然后计数为1
int l=0,r=0; //L表示横向,r表示纵向
a[0][0]=1;//第一个数
while(ans<n*m){//这个用于控制循环的次数
while(l+1<m&&a[r][l+1]==0)a[r][++l]=++ans;//注意是++l,而且是l+1<m保证下一个准备填的空在规定范围内
while(r+1<n&&a[r+1][l]==0)a[++r][l]=++ans;//且下一个要填的空是空的
while(l-1>=0&&a[r][l-1]==0)a[r][--l]=++ans;
while(r-1>=0&&a[r-1][l]==0)a[--r][l]=++ans;
}
for(int i=0;i<n;i++){
for(int j=0;j<m;j++)cout<<a[i][j]<<" ";
cout<<'\n';
}
以上方法写起来非常快捷,但通过填数控制循环次数容易想不到或者出错(也可能只有我这种蒟蒻才会想不到5555
所以
方法二:多用两个变量来控制填数,通过4个变量来确定已经填过数的范围
int l=0,r=m-1;//l表示当前纵坐标,r表示已经填了数的最小纵坐标;
int up=0,d=n-1;//同理
int ans=0;
while(l<=r&&up<=d) {//通过这俩循环
for(int i=l;i<=r;i++) a[up][i]=++ans;
for(int i=up+1;i<=d;i++) a[i][r]=++ans;
for(int i=r-1;i>=l&&up<d;i--) a[d][i]=++ans;
for(int i=d-1;i>up&&l<r;i--) a[i][l]=++ans;;
l+=1,r-=1,up+=1,d-=1;
}
for(int i=0;i<n;i++){
for(int j=0;j<m;j++)cout<<a[i][j]<<" ";
cout<<'\n';
}