藍橋杯 楊輝三角
阿新 • • 發佈:2022-03-18
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; } } }