杭州电子科技大学 Online Judge 之 “杨辉三角(ID2032)”解题报告

杭州电子科技大学 OnlineJudge
之 “
杨辉三角ID2032)”解题报告

巧若拙(欢迎转载,但请注明出处:http://blog.csdn.net/qiaoruozhuo

Problem Description

还记得中学时候学过的杨辉三角吗?具体的定义这里不再描述,你可以参考以下的图形:

1

1 1

1 2 1

1 3 3 1

1 4 6 4 1

1 5 10 10 5 1

Input

输入数据包含多个测试实例,每个测试实例的输入只包含一个正整数n(1<=n<=30),表示将要输出的杨辉三角的层数。

Output

对应于每一个输入,请输出相应层数的杨辉三角,每一层的整数之间用一个空格隔开,每一个杨辉三角后面加一个空行。

Sample Input

2 3

Sample Output

1

1 1

1

1 1

1 2 1

算法分析:

本题可以看作是动态规划算法的简单应用。根据空间复杂度的不同,我写了4个不同的实现方法。

算法1:采用最原始的动态规划思维,用一个二维数组把杨辉三角各行元素都记录下来。从第一行开始,利用递推关系:a[i][j] =a[i-1][j-1] + a[i-1][j];
计算出下一行的元素值。

算法2:观察递推关系,注意到第i行元素值由第i-1行确定,所以没必要把每一行的元素值都记录下来,只需记录两行就够了。我们可以用两个一维数组记录杨辉三角上一行和当前输出行元素,利用递推关系:curRow[j]
=preRow[j-1] + preRow[j];计算即可。

注意,每行元素输出后要及时把curRow[j]的值复制到preRow[j]中,以便迭代计算。

算法3:进一步观察递推关系,我们发现只需用到上一行的preRow[j-1]和 preRow[j]两个元素,所以无需把整行元素都记录下来,只需用两个变量迭代记录这两个元素值就行了。

可以设置两个变量left和right,分别存储preRow[j-1]
和 preRow[j]的值,然后利用递推关系:curRow[j] = left +right;更新curRow[j]的值,并及时更新left和right的值。

算法4:算法3中之所以需要两个变量,是因为preRow[j-1]和
preRow[j]的值都被更新了,需要先把它们记录下来,才能得到curRow[j]的值。如果我们从右往左处理,那被更新的元素就只有preRow[j],而preRow[j]由curRow[j]替代,即使被更新了也不影响推导curRow[j]的值。所以我们可以从右往左计算curRow[j]的值,这样根本无需用额外的变量来记录preRow[j-1]和
preRow[j]的值。

说明:

算法思想:动态规划。

数据结构:数组,基本数据类型。

时间复杂度:算法1O(n*n),其他算法O(n)。


12464653


2014-12-11 14:05:25


Accepted


2032


0MS


1060K


937 B


C


巧若拙


12464646


2014-12-11 14:04:39


Accepted


2032


15MS


1072K


983 B


C


巧若拙


12464635


2014-12-11 14:03:37


Accepted


2032


0MS


1064K


1034 B


C


巧若拙


12464617


2014-12-11 14:02:10


Accepted


2032


0MS


1060K


831 B


C


巧若拙

代码如下:

#include<stdio.h>
#define MAXROW 30

void Triangle_1(int row);//使用二维数组记录杨辉三角各行元素
void Triangle_2(int row);//使用两个一维数组记录杨辉三角上一行和输出行元素
void Triangle_3(int row);//使用一个一维数组和两个变量输出杨辉三角
void Triangle_4(int row);//使用一个一维数组从右往左记录杨辉三角

int main()
{
	int n;

	while (scanf("%d", &n) != EOF)
	{
		Triangle_1(n);
		printf("\n");
	}

    return 0;
}

void Triangle_1(int row)//使用二维数组记录杨辉三角各行元素
{
    int a[MAXROW+1][MAXROW+1] = {1};
    int i, j;

    for (i=1; i<=row; i++) //记录各行元素
    {
        for (j=1; j<=i; j++)
        {
            a[i][j] = a[i-1][j-1] + a[i-1][j];
            printf("%d", a[i][j]);
            if (j < i)
            	printf(" ");
        }
        printf("\n");
    }
}

void Triangle_2(int row)//使用两个一维数组记录杨辉三角上一行和输出行元素
{
    int preRow[MAXROW+1] = {0};//存储上一行元素
    int curRow[MAXROW+1] = {0};//存储输出行元素
    int i, j;

    preRow[1] = 1; //初始化数据
    for (i=1; i<=row; i++) //记录各行元素
    {
        for (j=1; j<=i; j++)
        {
            curRow[j] = preRow[j-1] + preRow[j];
        }
        for (j=1; j<=i; j++)
        {
            preRow[j] = curRow[j];
            printf("%d", curRow[j]);
            if (j < i)
            	printf(" ");
        }
        printf("\n");
    }
}

void Triangle_3(int row)//使用一个一维数组和两个变量输出杨辉三角
{
    int curRow[MAXROW+1] = {0};//存储输出行元素
    int i, j, left, right;

    curRow[1] = 1; //初始化数据
    for (i=1; i<=row; i++)
    {
    	left = 0; //初始化数据
        for (j=1; j<=i; j++)//记录输出行元素
        {
            right = curRow[j];
            curRow[j] = left + right;
            printf("%d", curRow[j]);
            if (j < i)
            	printf(" ");
            left = right;
        }
        printf("\n");
    }
}

void Triangle_4(int row)//使用一个一维数组从右往左记录杨辉三角
{
    int curRow[MAXROW+1] = {0};//存储输出行元素
    int i, j;

    curRow[1] = 1; //初始化数据
    for (i=1; i<=row; i++)
    {
        for (j=i; j>=1; j--) //从右往左记录输出行元素
        {
            curRow[j] += curRow[j-1];
        }
        for (j=1; j<=i; j++)
        {
            printf("%d", curRow[j]);
            if (j < i)
            	printf(" ");
        }
        printf("\n");
    }
}
时间: 2024-10-12 16:43:38

杭州电子科技大学 Online Judge 之 “杨辉三角(ID2032)”解题报告的相关文章

杭州电子科技大学Online Judge 之 “确定比赛名次(ID1285)”解题报告

杭州电子科技大学Online Judge 之 "确定比赛名次(ID1285)"解题报告 巧若拙(欢迎转载,但请注明出处:http://blog.csdn.net/qiaoruozhuo) Problem Description 有N个比赛队(1<=N<=500).编号依次为1,2,3,.....N进行比赛.比赛结束后.裁判委员会要将全部參赛队伍从前往后依次排名. 但如今裁判委员会不能直接获得每一个队的比赛成绩,仅仅知道每场比赛的结果.即P1赢P2,用P1.P2表示,排名时P

杭州电子科技大学Online Judge 之 “水仙花数(ID2010)”解题报告

杭州电子科技大学Online Judge 之 "水仙花数(ID2010)"解题报告 巧若拙(欢迎转载,但请注明出处:http://blog.csdn.net/qiaoruozhuo) Problem Description 水仙花数 春天是鲜花的季节,水仙花就是其中最迷人的代表,数学上有个水仙花数,他是这样定义的: "水仙花数"是指一个三位数,它的各位数字的立方和等于其本身,比如:153=1^3+5^3+3^3. 现在要求输出所有在m和n范围内的水仙花数. Inpu

杭州电子科技大学Online Judge 之 “漂浮的气球(ID1004)”解题报告

巧若拙(欢迎转载,但请注明出处:http://blog.csdn.net/qiaoruozhuo) 题目描述: Let the Balloon Rise Problem Description Contest time again! How excited it is tosee balloons floating around. But to tell you a secret, the judges' favoritetime is guessing the most popular pro

杨辉三角 x

杨辉三角是美丽的数学结晶,其结论往往多蕴含自然之美. ——以下内容均摘抄自题解. 例题: 洛谷P1762  偶数 正如这题所示,数据在n<=10^15的范围内则引导我们去寻找空间更节省,速率更高效的算法. 首先,很明显,杨辉三角之特点在于其行数即等于每行的数字数.因此,可以很容易使用求和公式求出1到n行一共有多少个数字. 其次,通过观察,可以发现,奇数个数比偶数个数更有规律,其规律在于: 每行奇数个数一定为2^k(k为自然数) 当行数恰为2^k(k为自然数)时,奇数个数为2^k,偶数个数为零 当

LeetCode (13) Pascal&#39;s Triangle (杨辉三角 )

题目描述 Given numRows, generate the first numRows of Pascal's triangle. For example, given numRows = 5, Return 从第三行开始,每行除了最左边和最右边两个数为1,其他数字都是上一行中相邻两个数字之和.根据上述规则可以写出下面的代码: class Solution { public: vector<vector<int> > generateRow1() { vector<in

杨辉三角

1 package com.llh.demo; 2 3 /** 4 * 杨辉三角 5 * 6 * @author llh 7 * 8 */ 9 public class Test { 10 /* 11 * 杨辉三角 12 */ 13 public static void main(String[] args) { 14 int[] a = new int[11]; 15 int num = 1; 16 // 17 for (int i = 1; i <= 10; i++) { 18 for (i

杨辉三角实例菱形实例

杨辉三角实例 public class Hui { public static void main (String [] args){ int [][] a =new int [10][10]; for(int i=0;i<a.length;i++){ for(int j=0;j<=i;j++){ if(j==0||i==j){ System.out.print(" "+(a[i][j]=1)); }else {a[i][j]=a[i-1][j-1]+a[i-1][j];

js算法集合(二) javascript实现斐波那契数列 (兔子数列) Javascript实现杨辉三角

js算法集合(二)  斐波那契数列.杨辉三角 ★ 上一次我跟大家分享一下做水仙花数的算法的思路,并对其扩展到自幂数的算法,这次,我们来对斐波那契数列和杨辉三角进行研究,来加深对Javascript的理解. 一.Javascript实现斐波那契数列 ①要用Javascript实现斐波那契数列,我们首先要了解什么是斐波那契数列:斐波那契数列(Fibonacci sequence),又称黄金分割数列.因数学家列昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为

使用Java打印杨辉三角

package 杨辉三角; import java.util.Scanner; public class 三角 { private static Scanner scn; public static void main(String[] args) { scn = new Scanner(System.in); System.out.println("请输入数据"); int n = scn.nextInt(); //定义一个二维数组 int [][] array = new int