蓝桥杯真题练习《杨辉三角形》

目录

题目:​

 几次失败的尝试:

满分代码:

总结:

参考博文:


题目:

 几次失败的尝试:

“40分”代码:

import java.util.Scanner;

public class PREV_284 {
    //杨辉三角问题
    public static void main(String[] args) {

        int n=2000;//杨辉三角层数  n的取值太大会报错 根据系统检测范围确定n的取值
        Scanner scanner = new Scanner(System.in);
        int N=scanner.nextInt();//输入被查找的数字
        tools_PREV_284 mytools_prev_284 = new tools_PREV_284();
        System.out.println(mytools_prev_284.YH_trangle_production(n,N));//输出被查找数字第一次出现的序号

    }
}
class tools_PREV_284 {
    //生成杨辉三角
    public long YH_trangle_production(int n,int N){
        int x=0;
        long a[][]=new long[n][];
        long b[]=new long[(1+n)*n/2];
        long index=-1;//索引
        for (int i = 0; i < n; i++) {
            //第二维不等长 第一行一列 第二行二列......
            a[i]=new long [i+1];//必须规定每行数组的列数 否则报错
            //每行首尾均为1
            a[i][0]=1;
            a[i][i]=1;
            //起止位置:第2--倒数第2
            for (int j = 1; j < a[i].length-1; j++) {
                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 < a[i].length; j++) {
                //赋值
                b[x]=a[i][j];
                x++;
            }
        }
        //查找指定数字的序号 b[]
        for (int i = 0; i < b.length; i++) {
            if (N==b[i]){
                index=i+1;
                break;
            }
        }
        //如果在数组中没有找到  那么这个数d
        if (index==-1){
            index=((N+1)*N)/2+2;
        }
        return index;



    }
}

第一次尝试遇到的问题:

1、确定杨辉三角层数:n

由于数组不可能存放太大数量的元素,所以不可能在数组b中存放过多杨辉三角数字。

在网上看到有的博主分析到:1900层是突破口(所以我把我的层数设置成了2000层)。

N如果在2000层内都没有出现过,那么N必定在第i层的第2个或者第3个。

2、代码太啰嗦

3、死脑筋,除了数组或许可以尝试利用集合arraylisy

“50分”代码:

import java.util.Scanner;

public class PREV_284 {
    //杨辉三角问题
    public static void main(String[] args) {

        int n=2000;//杨辉三角层数  n的取值太大会报错 根据系统检测范围确定n的取值
        Scanner scanner = new Scanner(System.in);
        int N=scanner.nextInt();//输入被查找的数字
        tools_PREV_284 mytools_prev_284 = new tools_PREV_284();
        System.out.println(mytools_prev_284.YH_trangle_production(n,N));//输出被查找数字第一次出现的序号

    }
}
class tools_PREV_284 {
    //生成杨辉三角
    public long YH_trangle_production(int n,int N){
        int x=0;
        long a[][]=new long[n][];
        long b[]=new long[(1+n)*n/2];
        long index=-1;//索引
        int the_num_rows=2001;//
        boolean flag=true;
        for (int i = 0; i < n; i++) {
            //第二维不等长 第一行一列 第二行二列......
            a[i]=new long [i+1];//必须规定每行数组的列数 否则报错
            //每行首尾均为1
            a[i][0]=1;
            a[i][i]=1;
            //起止位置:第2--倒数第2
            for (int j = 1; j < a[i].length-1; j++) {
                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 < a[i].length; j++) {
                //赋值
                b[x]=a[i][j];
                x++;
            }
        }
        //查找指定数字的序号 b[]
        for (int i = 0; i < b.length; i++) {
            if (N==b[i]){
                index=i+1;
                break;
            }
        }
        if (index!=-1){
            return index;//目标在数组b内 则返回对应位置
        }
        //所找数字不在数组b内时(待优化 一个个算太费时间)
        else{//目标不在数组内 则按照公式返回
            while(flag){
                if (N==the_num_rows){
                    flag=false;
                    //return the_num_rows*(1+the_num_rows)/2+2;
                    index=the_num_rows*(1+the_num_rows)/2+2;
                }
                if (N==the_num_rows*(the_num_rows-1)/2){
                    flag=false;
                    //return the_num_rows*(1+the_num_rows)/2+3;
                    index=the_num_rows*(1+the_num_rows)/2+3;
                }
                the_num_rows++;
            }
            return index;
        }

    }
}

第二次尝试遇到的问题:

我的测试输出结果与系统测试输出不一样 我不知道为什么!

再次修改代码(50分):

import java.util.Scanner;

public class PREV_284 {
    //杨辉三角问题
    public static void main(String[] args) {

        int n=1900;//杨辉三角层数  n的取值太大会报错 根据系统检测范围确定n的取值
        Scanner scanner = new Scanner(System.in);
        int N=scanner.nextInt();//输入被查找的数字
        tools_PREV_284 mytools_prev_284 = new tools_PREV_284();
        System.out.println(mytools_prev_284.YH_trangle_production(n,N));//输出被查找数字第一次出现的序号

    }
}
class tools_PREV_284 {
    //生成杨辉三角
    public long YH_trangle_production(int n, int N){
        int x=0;
        long a[][]=new long[n][];
        long b[]=new long[(1+n)*n/2];
        long index=-1;//索引
        //int the_num_rows=1900;//
        boolean flag=true;
        int rows=0;
        for (int i = 0; i < n; i++) {
            //第二维不等长 第一行一列 第二行二列......
            a[i]=new long [i+1];//必须规定每行数组的列数 否则报错
            //每行首尾均为1
            a[i][0]=1;
            a[i][i]=1;
            //起止位置:第2--倒数第2
            for (int j = 1; j < a[i].length-1; j++) {
                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 < a[i].length; j++) {
                //赋值
                b[x]=a[i][j];
                x++;
            }
        }
        //查找指定数字的序号 b[]
        for (int i = 0; i < b.length; i++) {
            if (N==b[i]){
                index=i+1;///
                break;
            }
        }
        if (index==-1){
            rows=(int)(Math.sqrt(N));
            while(rows*(rows-1)/2<N){
                if (N==rows*(rows-1)/2){
                    index=rows*(rows+1)/2+3;/
                    break;
                }
                rows++;
            }
            if (index==-1){
                rows=N;
                index=rows*(rows+1)/2+2;
            }

        }

    return index;
    }
}

不知道哪里出了问题 继续修改。。。。。。

破案了!是因为数据类型的问题导致出错long转化int数值溢出

满分代码:

100分代码:

import java.util.Scanner;

public class PREV_284 {
    //杨辉三角问题
    public static void main(String[] args) {

        int n=1901;//杨辉三角层数  n的取值太大会报错 根据系统检测范围确定n的取值
        Scanner scanner = new Scanner(System.in);
        int N=scanner.nextInt();//输入被查找的数字
        tools_PREV_284 mytools_prev_284 = new tools_PREV_284();
        System.out.println(mytools_prev_284.YH_trangle_production(n,N));//输出被查找数字第一次出现的序号

    }
}
class tools_PREV_284 {
    //生成杨辉三角
    public long YH_trangle_production(int n, int N){
        int x=0;
        long a[][]=new long[n][];
        long b[]=new long[(1+n)*n/2];
        long index=-1;//索引
        //int the_num_rows=1900;//
        boolean flag=true;
        long rows=0;
        for (int i = 0; i < n; i++) {
            //第二维不等长 第一行一列 第二行二列......
            a[i]=new long [i+1];//必须规定每行数组的列数 否则报错
            //每行首尾均为1
            a[i][0]=1;
            a[i][i]=1;
            //起止位置:第2--倒数第2
            for (int j = 1; j < a[i].length-1; j++) {
                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 < a[i].length; j++) {
                //赋值
                b[x]=a[i][j];
                x++;
            }
        }
        //查找指定数字的序号 b[]
        //经过测试:第0层到第1900层出现过的数字 都能准确的返回对应序号
        for (int i = 0; i < b.length; i++) {
            if (N==b[i]){
                index=i+1;
                break;
            }
        }
        //现在考虑
        if (index==-1){
            rows=(int)(Math.sqrt(2*N));
            while(rows*(rows-1)/2<N){
                rows=rows+1;
                if (rows*(rows-1)/2==N){
                    index=rows*(rows+1)/2+3;
                    break;
                }
                index=-2;
            }
            if (index==-2){
                rows=N;
                index=rows*(rows+1)/2+2;
            }
        }
        return index;
    }
}

对我来说,上面这段代码修改的关键是:将rows的类型由int改为long 然后就出来了

总结:

1、找规律

不可能将所有数据储存在数组里,经过分析(见参考博文)发现大约在1900行之后,目标数字N只可能出现在某行的第2或者第3的位置

2、

参考博文:

https://blog.csdn.net/qq_39529682/article/details/122174492

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值