蓝桥杯真题:杨辉三角形
生活随笔
收集整理的這篇文章主要介紹了
蓝桥杯真题:杨辉三角形
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
具體分析可以看:
第十二屆藍橋杯B組省賽楊輝三角形題解_Nervous_46216553的博客-CSDN博客
輸入輸出樣例
示例 1
輸入
6輸出
13評測用例規模與約定
對于?20%的評測用例,1≤N≤10?; 對于所有評測用例,1≤N≤1000000000。
運行限制
- 最大運行時間:1s
- 最大運行內存: 256M
?第一眼的思路是打表算呢,打算從組合數一個一個算來著這樣的時間復雜度挺高的。
第二種思路是找路徑:用C(m,n)的組合數來看,當前位置比N大則向左走,小則向下走一次,向中間走一次:
#include<iostream> using namespace std; long long m;//行-1 long long n;//列-1 long long v;//C(m,n)的值 long long temp;//臨時變量用來提速 void down(){//下一層v=v*(m+1)/(m-n+1);++m; } void left(){//左一個v=v*n/(m-n+1);--n; } void center(){//嘗試往中間靠temp=v*(m-n)/(n+1);//如果右邊更大就向右,否則不用動if(v<temp){v=temp;++n;} } int main(){long long N,ans=0;cin >> N;v=1;m=1;n=0;while(1){//查找if(v<N){down();center();}else if(v>N){left();}else{break;}}//檢查位置正確性//cout << m+1 << " " << n+1 << endl;ans=m*(m+1)/2+n+1;//前面的等差數列求和然后加當前行if(ans==2)ans=1;cout << ans << endl;return 0; }第三種思路是二分:
利用列的遞增性質我們進行二分:
#include<iostream> using namespace std; long long N; long long P(long long m,long long n){//計算m行n列的值--m;//P(m,m)=C(m-1,n-1)--n;n=max(n,m-n);//C(m,n)==C(m,m-n)long long ans=1;for(long long i=1;i<=(m-n);++i){ans*=(n+i);ans/=i;//由上文定理一定能除盡if(ans>N){//及時退出防止溢出(只用大小關系,不需要準確值)return N+1;}}return ans; } long long find(long long n){//二分查找第n列long long gap=1<<30,m=n;//不存在m不小于n的位置!!!while(gap){if(P(m,n)<N){//小了往前跑m+=gap;}else if(P(m,n)>N){//大了間距縮小往前找gap/=2;//(8,4,2,1一定能湊出<=15的所有數(就是二進制表示嗎))m-=gap;}else{return (m)*(m-1)/2+n;//前面的行等差數列求和然后加當前行}}return (N+1)*(N+1);//找不到就返會一個一定超了的位置,別的如果找到一定排的靠前。 } int main(){long long ans=1;cin >> N;if(N!=1)//因為第一列全是1,值相等所以不可以用二分查找ans=find(2);for(int i=3;i<=100;++i){//第N行總和2^n(每行的總和都是上一行的兩倍),最大值肯定>(2^n)/n,左側100列以內絕對足夠搜出10^9的數值(因為前文組合數計算優化過了,根本不怕溢出,查幾列隨便二分查找的速度很快很快)ans=min(ans,find(i));//找最小的}cout << ans << endl;return 0; }總結
以上是生活随笔為你收集整理的蓝桥杯真题:杨辉三角形的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python --- 二分查找算法
- 下一篇: MySQL via EF6 的试用报告