蓝桥杯每日N题(杨辉三角形)

大家好 我是寸铁 希望这篇题解对你有用,麻烦动动手指点个赞或关注,感谢您的关注

不清楚蓝桥杯考什么的点点下方

考点秘籍

想背纯享模版的伙伴们点点下方

蓝桥杯省一你一定不能错过的模板大全(第一期)

蓝桥杯省一你一定不能错过的模板大全(第二期)

蓝桥杯省一你一定不能错过的模板大全(第三期)

蓝桥杯省一你一定不能错过的模板大全(第四期)!!!

想背注释模版的伙伴们点点下方

蓝桥杯必背第一期

蓝桥杯必背第二期

往期精彩回顾

蓝桥杯上岸每日N题 第一期(一)!!!

蓝桥杯上岸每日N题第一期(二)!!!

蓝桥杯上岸每日N题第一期(三)!!!

蓝桥杯上岸每日N题第二期(一)!!!

蓝桥杯上岸每日N题第三期(一)!!!

蓝桥杯上岸每日N题 第四期(最少刷题数)!!!

蓝桥杯上岸每日N题 第五期(山)!!!

蓝桥杯上岸每日N题 第六期(求阶乘)!!!

蓝桥杯上岸每日N题 第七期(小猫爬山)!!!

蓝桥杯上岸每日N题 第八期 (全球变暖)!!!

蓝桥杯每日N题 (消灭老鼠)

操作系统期末题库 第九期(完结)

LeetCode Hot100 刷题(第三期)

idea创建SpringBoot项目报错解决方案

数据库SQL语句(期末冲刺)

想看JavaB组填空题的伙伴们点点下方

填空题

竞赛干货

算法竞赛字符串常用操作大全

蓝桥杯上岸必刷!!!(模拟/枚举专题)

蓝桥杯上岸必背!!! (第三期 DP)

蓝桥杯上岸必背!!!(第四期DFS)

蓝桥杯上岸必背!!!(第五期BFS)

蓝桥杯上岸必背!!!(第六期树与图的遍历)

蓝桥杯上岸必背!!!(第七期 最短路算法)

蓝桥杯上岸必背!!!(第八期 简单数论)

蓝桥杯上岸必刷!!!(进制、数位专题)

蓝桥杯上岸考点清单 (冲刺版)!!!

蓝桥杯上岸必背模板 (纯享版)

考点:二分+求组合数

分析

要在这堆数字中找到n
观察发现:
(1)三角形左右两边的数字对称
我们只需要看左半边的数字即可

(2)画一条中轴线在中间
发现中轴线上的点的值为C(2n,n)
找的时候,从内往外找,依次去枚举每一斜行。
为什么?
假设我们找到n,那外面的数字必然是小于n的,所以我们从内开始去找n。
第一次找到的数必定在左边且减少我们的枚举次数。

接下来怎么做?
我们从第16斜行去枚举中轴线上的起点开始,依次去枚举每一斜行
从中查找组合数,看能否二分出答案来

概念理清:

组合数:C(a,b)
a:底数–>当前枚举的斜行数–>二分的答案(r)
**b:**真数–>k

二分过程

不清楚二分的过程可以看下面的图:

蓝桥杯每日N题(杨辉三角形)_第1张图片

图形解读:

组合数:C(a,b)
a:底数–>当前枚举的斜行数–>二分的答案(r)
b:真数–>k

枚举的是每一斜行,从中轴线的起点开始。
相当于我check一个k(枚举的斜行数),我二分的是当前这一斜行的组合数的底数。
根据二分原理,去更新mid的值。
再看我当前枚举的这一斜行C(mid,k)能否找到n
枚举这一斜行都找不到后,我再往前去枚举上一斜行,直至第一个斜行

求组合数

public static long C(long a,long b) {
	long res=1;
	for(long i=a,j=1;j<=b;i--,j++) {
		res=res*i/j;
		if(res>n)return res;
	}
	return res;
    }

杨辉三角形数字定位技巧

在数字序列的第几个位置(r+1)*r/2+k+1
r:组合数的底数

代码详解

import java.util.*;
public class Main{
  static int n;
  public static long C(long a,long b) {
     //求组合数
	long res=1;
	for(long i=a,j=1;j<=b;i--,j++) {
		res=res*i/j;
		if(res>n)return res;
	}
	return res;
    }
    
    public static boolean check(int k) {
	long l=2*k,r=Math.max(l,n);
    //记得l,n取max,否则最一开始当l>r时无法二分
	//C(l,r):l表示的是组合数底数的下界
	//       r表示的是组合数底数的上界
	
	//二分
	while(l<r) {
    long mid=l+r>>1;
	if(C(mid,k)>=n)r=mid;
	//更新我当前枚举的这一斜行组合数的底数
	//让它往上或往下走
	else l=mid+1;
	}
	
	if(C(r,k)!=n)return false;
	//找不到等于n的数,就返回false,去枚举下一斜行。
	
//C(r,k):二分出的组合数
//k:k表示的是列数,由于是从第0行开始,所以是k+1
//这样可以得出数字n在第几列。

//r:r表示的是行数,(1+r)*r/2可以得到数字在哪一行
//(1+r)*r/2再加上移动的第几列即k+1
//这样可以得到n在整个序列中是在第几个位置。
	System.out.println((1+r)*r/2+k+1);
	return  true;
    }
    
    public static void main(String []args){
        Scanner sc=new Scanner(System.in);
        n=sc.nextInt();
        for(int i=16;;i--){
            //C16的32小于1e9
            //从16斜行开始枚举
            //找到满足条件的数就break
            if(check(i))break;
        }
    }
}

创作不易,欢迎大家多多关注,Thankyou~

你可能感兴趣的:(蓝桥杯上岸,蓝桥杯,算法,模板,java,二分,杨辉三角形)