试题 历届真题 杨辉三角形 【第十二届】【省赛】【B组】

一、题目描述

二、题目初步分析

杨辉三角大家都会,这题多了一个判断,相等就输出位置,难点在于:n可以为10亿,运行次数过多会超内存,超时。

三、脑中第一个想法写出的答案(暴力求解,20分)

import java.util.*;
public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int num = sc.nextInt();
		int count = 1;
		long[][] a = new long[num+1][];
		for(int i=0;i<a.length;i++) {
			a[i] = new long[i+1];
			for(int j=0;j<a[i].length;j++) {
				if(j==0||j==i) {
					a[i][j]=1;
				}else {
					a[i][j] = a[i-1][j-1]+a[i-1][j];
				}
			}
		}
		for(int i=0;i<a.length;i++) {
			for(int j=0;j<=i;j++) {
				if(num==a[i][j]) {
					System.out.println(count);
					return;
				}else {
					count++;
				}
			}
		}
	}
}

经过多次尝试,暴力破解都无法成功,在网上查阅资料后,找到了一条比较简单容易理解的思路,做个整理,供大家参考学习。 

四、满分解答

1.思路分析

逐行求数值,并查找是否有需要查找的值,若有,则输出位置;若没有,则转下一行。

2.具体流程

如上表,黄色部分为默认值或初始值。从i-1那行开始求值,从右往左求,绿色区域部分是可能需要求值的区域。

能够发现,当i=1时,arr[1]=arr[1]+arr[0];当i=2时,arr[2]=arr[2]+arr[1],arr[1]=arr[1]+arr[0];......;当i=n时,arr[n]=arr[n]+arr[n-1],arr[n-1]=arr[n-1]+arr[n-2],...... 。

因为在求出一行的值之后就进行查找,所以如果没有找到,下一行的值可以覆盖这一行的值,就不需要定义二维数组,可以节省不少内存。

由于题目测试数据达到10亿,暴力求解是行不通的,通过观察可以发现,第一列的值都为1,不用管;第二列的值为n-1,要达到10亿,需要的行数还是很多,没法定义;第三列除了起始两个元素为0之外,剩下的元素为1,3,6(1+2+...+i的累加序列)这样有规律的序列,若要使数据值超过10亿,i需要达到44721行,加上起始的两个0,一共需要44723行,此时,使用long类型的数据就可以存下,超过10亿之后,若数值仍没有出现,我们也就不用再算了,直接使用当前行第三列的值(n+1)*n/2+2即可。由此,可得到如下程序:

import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        long n = scan.nextLong();//输入值,查找
        long[] arr =new long[44725];
        arr[0]=1;
        long k=1L;//k来定义位置(已经查找过的前i-1行)
        if (n == 1) {
            System.out.println(1);
            return;
        }
        for (int i = 1;i<44725; i++) {
            for (int j = i; j>=1; j--) {
                arr[j] += arr[j - 1];
                if (arr[j] == n) {
                    System.out.println(k + i-j + 1);//最后的+1是加上最后一行第一个1,因为是默认值,没有参与计算,所以需要加上那个位置,由于杨辉三角是对称的,i-j的关系,稍加思索应该也可以被发现
                    return;//如果找到了就结束
                }
            }
            k+=(i+1);
        }
        System.out.println(((1 + n) * n / 2) + 2);
    }
}

至此,问题就被完美的解决了。若有些同学只考虑超过10亿的情况,也可以得到50分。 

  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

zhengyanyan123

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

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

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

打赏作者

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

抵扣说明:

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

余额充值