蓝桥杯 杨辉三角

转载大佬的链接

import java.util.*;
public class Main {
	/**
	 * 组合数和杨辉三角:第i行第j列的数都是组合数C(i, j) (i,j从0开始)
        C(n, 1) = n --> 对应从左向右看斜着的第二列! ---> 一定有解
    由于杨辉三角左右对称(C(a, b) == C(a, a-b)),又由于找第一次出现,因此一定在左边,右边可以直接删掉!
            			1  ---> C(0, 0)
          			  1 
        			1   2  ---> C(2, 1)
      			  1   3                             ---> C(2n, n)
    			1   4   6  ---> C(4, 2)
  			  1   5   10
			1   6   15  20 ---> C(6, 3)
    n最大1e9, C(34, 17) > 1e9, C(32, 16) < 1e9,因此只要枚举前16个斜行即可 
	 * */
	
	// C(a, b) = a!/(b!(a-b)!) = a * (a-1) .. b / b!
	public static long C(long a,long b,long n) {
		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(long k,long n) {
		//找左边界 因为需要找第一次出现,所以是左边界模板
		 //此处是二分模板
		 // l 是斜线右上角的行数 r 是斜线左下角的行数
		long l = 2 * k, r = Math.max(n, l);
		while(l<r) {
			long mid = (l+r)/2;
			if(C(mid,k,n)>=n) r=mid;
			else l = mid + 1;
		}
		//判断找到的值不是与之前输入的值相等
		if(C(r,k,n)!=n) {
			return false;
		}
		//找到的值 那么根据公式返回第一次出现的位置
		//组合数公式
		System.out.print((r+1)*r/2+k+1);
		return true;
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner reader =new Scanner(System.in);
		long n=reader.nextLong();
		for(long k=16;;k--) {
			//找到数 则停止
			if(check(k,n)) break;
		}
	}
 
}

作者:静默虚空
欢迎任何形式的转载,但请务必注明出处。
限于本人水平,如果文章和代码有表述不当之处,还请不吝赐教。

posted @   Chenyi_li  阅读(65)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示