1097: 蛇行矩阵

题目 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;
}

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值