标题:杭州电子科技大学 Online Judge 之 “杨辉三角(ID2032)”解题报告
只看楼主
巧若拙
Rank: 4
来 自:宁波余姚
等 级:业余侠客
威 望:1
帖 子:159
专家分:273
注 册:2014-8-24
结帖率:46.15%
已结贴  问题点数:3 回复次数:3 
杭州电子科技大学 Online Judge 之 “杨辉三角(ID2032)”解题报告
杭州电子科技大学 Online Judge 之 “杨辉三角(ID2032)”解题报告
巧若拙(欢迎转载,但请注明出处:http://blog.
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");
    }
}
搜索更多相关主题的帖子: 杨辉三角 Online 正整数 杭州 大学 
2014-12-12 12:53
wp231957
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:神界
等 级:版主
威 望:422
帖 子:13681
专家分:53296
注 册:2012-10-18
得分:2 
楼主厉害

DO IT YOURSELF !
2014-12-12 13:18
longwu9t
Rank: 11Rank: 11Rank: 11Rank: 11
等 级:小飞侠
威 望:6
帖 子:732
专家分:2468
注 册:2014-10-9
得分:2 
这是茴香豆有多少种写法的意思么
不过还真是有学问啊
copy闪人

Only the Code Tells the Truth             K.I.S.S
2014-12-12 13:41
巧若拙
Rank: 4
来 自:宁波余姚
等 级:业余侠客
威 望:1
帖 子:159
专家分:273
注 册:2014-8-24
得分:0 
最近学习动态规划策略,动态规划很难理解,于是找了一些相关题目,试图从动态规划的角度去理解,并从低效到高效,天真算法到优化算法进行比较分析,希望自己能够理解得到位一点,记录下来以免今后忘记,同时谢谢你的关注。
2014-12-12 18:09



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-439862-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.428296 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved