“数字直角三角形”的循环简化

【题目描述】

给出n(1<=n<=13),请输出一个直角边长度是n的数字直角三角形。

【样例输入】

5

【样例输出】

0102030405

06070809

101112

1314

15

【题目来源】

洛谷P5721 【深基4.例6】数字直角三角形

【解析】

本题的样例输出一眼望过去就是像一个矩阵,或者叫三角阵貌似更形象。我家娃断言,老师教过的,这种要使用一个x坐标、一个y坐标,因此要用两重循环。

看起来确实是这样:

①大循环:一行一行的输出,这是一种重复作业,可以用循环。

②小循环:一个数一个数的输出,后一个数是前一个数加1,这是一种有规律重复作业,可以用循环。

标准代码:

#include<cstdio>
using namespace std;
int main(){
    int cnt=0, n;
    scanf("%d", &n);
    for(int i=1; i<=n; i++){
        for(int j=1; j<=n+1-i; j++){
            printf("%02d", ++cnt);
        }
        printf("\n");
    }
    return 0;
}

代码中的i相当于y坐标,j相当于x坐标。本题的关键是要求出换行的位置,也就是每行中最后一个要输出的数的x坐标,即每行j的最大值j_max。

以n=5为例:

换行

i

j_max

规律

1

1

5

1+5=6

2

2

4

2+4=6

3

3

3

3+3=6

4

4

2

4+2=6

5

5

1

5+1=6

不难发现一个规律,i+j_max=6=5+1=n+1,即j_max=n+1-i。

但是老金看到这道题的第一感觉是应该可以用一层循环求解,当我提出这个想法时,却被我家娃一顿嘲笑。

他说老师教过,要用x坐标、y坐标。

只能感叹教育的僵化,希望老师们能意识到,教学生时尽量不要用“要”这个字,而应用“可以”、“也许”、“试试”之类的词。

之所以我认为可以用一层循环,主要是因为输出的数的规律是一致的,都是递增1,只不过要在不同的位置输出换行符。

所以,实现一层循环的难点依然是找到换行的位置。

因为只有一层循环,迭代的变量自然就是要输出的数。所以此时便没有了y坐标,就不能再用上表中与y坐标的和是固定值的规律了。

但是在上表中,单看j_max这一例也能一眼看出一个规律,就是值从n开始,每次递减1。咱们就可以利用这个规律实现一层循环。方法就是再引入一个累加器j++,每行开始输出时将其值置为0,当它累加到j_max的时候输出换行符。

代码如下:

#include<stdio.h>
int main(){
    int n, j=0;
    scanf("%d", &n);
    for(int i=1;;i++){
        j++;
        printf("%02d", i);
        if(j==n){
            printf("\n");
            n--;
            j=0;
        }
        if(n==0) break;
    }
    return 0;
}

还有另外一个思路,就从输出的数中找出换行的位置,还是以n=5为例,假设输出的数为i。

换行

i

规律

1

5

0+5

2

9

5+4

3

12

9+3

4

14

12+2

5

15

14+1

每次输出换行符的位置都是上一个位置加上一个n--。代码如下:

#include<stdio.h>
int main(){
    int n, i_newline;
    scanf("%d", &n);
    i_newline=n;
    for(int i=1;;i++){
        printf("%02d", i);
        if(i==i_newline){
            printf("\n");
            n--;
            i_newline+=n;
        }
        if(n==0) break;
    }
    return 0;
}

还有一点,上面两个一层循环的退出条件还可以直接设置在循环条件判断处。

for(int i=1;i<=n*(n+1)/2;i++)

想想为什么?

当然,此时代码中就不能随便改n的值了,即不能直接用n—了,而要先把n的值赋给另一个变量m,让m--。

  • 23
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

金创想

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值