ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

杨辉三角形--2021蓝桥杯Java组

2022-01-03 16:58:01  阅读:355  来源: 互联网

标签:down head -- up long 蓝桥 int 杨辉三角


杨辉三角形–2021蓝桥杯Java组

题目描述

下面的图形是著名的杨辉三角形:

在这里插入图片描述

如果我们按从上到下、从左到右的顺序把所有数排成一列,可以得到如下数列:1,1,1,1,2,1,1,3,3,1,1,4,6,4,1,⋯
给定一个正整数 NN,请你输出数列中第一次出现 NN 是在第几个数?

输入描述

输入一个整数 NN。

输出描述

输出一个整数代表答案。

输入输出样例

示例 1
输入

6
输出

13

评测用例规模与约定

对于 20%​​ 的评测用例,1≤N≤10​; 对于所有评测用例,10000000001≤N≤1000000000。

运行限制

最大运行时间:1s
最大运行内存: 256M

分析:

  1. 杨辉三角:第一个数为第零行第零列,则我们观察发现杨辉三角第i行第j列的数字为组合数C(i, j)
  2. 杨辉三角每行最大的数为C(i, i / 2), 每列j的最小有效行(之前没出现的数字)是 2 * j行,最大有效行是给定数字的n 的n行(第二列1到n)
  3. 注意杨辉三角数字增大按列增大比按行增大快,所以我们按列找。根据数据给定N范围确定最大的列为17,C(33,17) = 1166803110 > 1000000000
  4. 本题通过所有样例要写出O(logN)的算法所以不能暴力解决(打表遍历超时,后面大数即使是long也会会溢出)数据范围内一共只遍历17个列,行最大可到1000000000 故我们再遍历列的基础上对行进行二分查找!
  5. 本题还是有点东西,考场AC有点难度

AC代码:

import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改

public class Main {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int n = scan.nextInt();
        for(int k = 17; k >= 0; k--){
            int  head = 2 * k; //每列最小有效行
            int tail = Math.max(n, head); // 每列最大有效行
            int r = -1;
            while(head <= tail){
                int mid = (head + tail) >> 1;
                if(combination(mid, k, n) >= n){
                    tail = mid - 1;
                    r = mid;
                }else{
                    head = mid + 1;
                }
            }
            if(combination(r, k, n) == n){
                System.out.println((long)(r +1 ) * r/2 + k + 1);
                break;
            }
        }
        scan.close();
    }


    static long gcd(long a, long b) {
        return b == 0 ? a : gcd(b, a % b);
    }

	//算第i行第j列的组合数 与 给定数target的大小
	//运算组合过程中判断,如果比target大,直接返回当前数字
	//这里在小于等于target的时候才会将C(i,j)组合数算完并返回
    static long combination(long n , long k, long target){
        long up = 1, down = 1;
        if(k > n / 2){
            k = n - k;
        }
        for (int i = 1; i <= k; i++) {
            up *= n - i + 1;
            down *= i;
            long g = gcd(up, down);
            up /= g;
            down /= g;
            if(up / down > target){
                return up /down;
            }
        }
        return up / down;
    }
}

标签:down,head,--,up,long,蓝桥,int,杨辉三角
来源: https://blog.csdn.net/XTU_xyx/article/details/122288926

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有