Round Numbers--楊輝三角,組合數學
大致題意:
輸入兩個十進位制正整數a和b,求閉區間 [a ,b] 內有多少個Round number
所謂的Round Number就是把一個十進位制數轉換為一個無符號二進位制數,若該二進位制數中0的個數大於等於1的個數,則它就是一個Round Number
注意,轉換所得的二進位制數,最高位必然是1,最高位的前面不允許有0
規定輸入範圍: 1<= a <b<=2E
用組合做
很猥瑣的題,我首先說說猥瑣的地方,再說說解題思路,有四點很猥瑣:
(1)規定輸入範圍: 1<= a <b<=20E
輸入的數是一個接近大數的非大數,int可以儲存
網上看很多同學都說要用到精度,其實完全沒必要,int
但是即使這樣,面對這題也不能鬆懈啊!bin[]邊界的最小值為35 !!。
(2)bin[]陣列若果定義為區域性陣列,等著WA吧!
我找不到任何原因為什麼會這樣,bin不管是全域性定義還是區域性定義,本地是完全AC的,上傳就出問題了,區域性WA,全域性AC。
人家有強權,我被迫把傳參del掉,把bin改為全域性,鬱悶!猥瑣!
(3)組合數打表,同(1)的猥瑣,c[][]邊界的最小值為33,就是說如果定義組合表的大小比
c[33][33]小的,就等著RE吧!
還有就是這個演算法有一個違背常識的處理,要把c[0][0]=1,不然某些最終結果會少1
(4)輸入不能用迴圈輸入while(cin>>…),不然你就等著OLE (就是Output Limit Excessed,很少見吧!)。不知道資料庫是怎麼回事,輸入竟然不會根據讀取資料結束而結束,而是無限輸出最後一次輸入所得的結果……老老實實一次輸出就end file吧!
解題思路:
組合數學題,不知道為什麼會被歸類到遞推數學,可能是因為楊輝三角和組合數之間的關係。。。
我根據我寫的程式講解好了
要知道閉區間 [a ,b] 內有多少個Round number,只需要分別求出
閉區間 [0 ,a] 內有T個RN
閉區間 [0 ,b+1] 內有S個RN
再用 S – T 就是閉區間 [a ,b]
至於為什麼是 b+1,因為對於閉區間 [0 ,k] ,我下面要說的演算法求出的是比k小的RN數,就是說不管 k是不是RN, 都沒有被計算在內,所以若要把閉區間[a ,b]的邊界a和b都計算在內,就要用上述的處理方法。
現在問題的關鍵就是如何求[0 ,k]內的RN數了
首先要把k轉化為二進位制數bin-k,並記錄其位數(長度)len
那麼首先計算長度小於len的RN數有多少(由於這些數長度小於len,那麼他們的值一定小於k,因此在進行組合時就無需考慮組合所得的數與k之間的大小了)
for(i=1;i<bin[0]-1;i++) //bin[0]記錄的是二進位制數的長度len
for(j=i/2+1;j<=i;j++)
sum+=c[i][j];
可以看到,i<len-1 ,之所以減1,是因為這些長度比len小的數,最高位一定是1,那麼剩下可供放入數字的位數就要再減少一個了
這條程式得到的sum為
1表示當前處理的二進位制數的最高位,X表示該二進位制數待放入數字的位
顯然這段程式把二進位制數0 排除在外了,這個是最終結果沒有影響的,因為最後要把區間[a , b]首尾相減,0存不存在都一樣了。
然後計算長度等於len的RN數有多少(由於這些數長度等於len,那麼他們的值可能小於k,可能大於k,因此在進行組合時就要考慮組合所得的數與k之間的大小了)
int zero=0; //從高位向低位搜尋過程中出現0的位的個數
for(i=bin[0]-1;i>=1;i--)
if(bin[i]) //當前位為1
for(j=(bin[0]+1)/2-(zero+1);j<=i-1;j++)
sum+=c[i-1][j];
else
zero++;
之所以初始化i=bin[0]-1,是因為bin[]是逆向存放k的二進位制的,因此要從高位向低位搜尋,就要從bin[]後面開始,而要 bin[0]-1 ,是因為預設以後組合的數長度為len,且最高位為1,因此最高位不再搜尋了。
那麼問題的關鍵就是怎樣使得以後組合的數小於k了
這個很簡單:
從高位到低位搜尋過程中,遇到當前位為0,則不處理,但要用計數器zero累計當前0出現的次數
遇到當前位為1,則先把它看做為0,zero+1,那麼此時當前位後面的所有低位任意組合都會比k小,找出這些組合中RN的個數,統計完畢後把當前位恢復為原來的1,然後zero-1,繼續向低位搜尋
那麼問題就剩下噹噹前位為1時,把它看做0之後,怎樣去組合後面的數了
此時組合要考慮2個方面:
(1) 當前位置i後面允許組合的低位有多少個,我的程式由於bin是從bin[1]開始儲存二進位制數的,因此當前位置i後面允許組合的低位有i-1個
(2) 組合前必須要除去前面已出現的0的個數zero
我的程式中初始化j=(bin[0]+1)/2-(zero+1), j本來初始化為(bin[0]+1)/2就可以了,表示對於長度為bin[0]的二進位制數,當其長度為偶數時,至少其長度一半的位數為0,它才是RN,當其長度為奇數時,至少其長度一半+1的位數為0,它才是RN。
但是現在還必須考慮前面出現了多少個0,根據前面出現的0的個數,j的至少取值會相應地減少。 -(zero+1) ,之所以+1,是因為要把當前位bin[i]看做0
然後到了最後,剩下一個問題就是怎樣得到每一個的值,這個我發現很多同學都是利用打表做的,利用的就是組合數與楊輝三角的關係(建立一個二維陣列C[n]
就能看到他們之間關係密切啊!區別就是頂點的值,楊輝三角為1,組合數為0)
其實這個“關係”是有數學公式的
好好體會一下吧!
其實組合數也可以直接用計算方法做(n的規模可以至少擴充套件到1000),不過這裡n的規模只有26,打表應該是更快的,有興趣學習用計算方法做組合數的同學可以聯絡我,這個要用另外的數學方法處理。
我QQ289065406 O(∩_∩)O哈哈~
//Memory Time
//224K 16MS
#include<iostream>
using namespace std;
int c[33][33]={0};
int bin[35]; //十進位制n的二進位制數
/*打表,計算nCm*/
void play_table(void)
{
for(int i=0;i<=32;i++)
for(int j=0;j<=i;j++)
if(!j || i==j)
c[i][j]=1;
else
c[i][j]=c[i-1][j-1]+c[i-1][j];
// c[0][0]=0;
return;
}
/*十進位制n轉換二進位制,逆序存放到bin[]*/
void dec_to_bin(int n)
{
bin[0]=0; //b[0]是二進位制數的長度
while(n)
{
bin[++bin[0]]=n%2;
n/=2;
}
return;
}
/*計算比十進位制數n小的所有RN數*/
int round(int n)
{
int i,j;
int sum=0; //比十進位制數n小的所有RN數
dec_to_bin(n);
/*計算長度小於bin[0]的所有二進位制數中RN的個數*/
for(i=1;i<bin[0]-1;i++)
for(j=i/2+1;j<=i;j++)
sum+=c[i][j];
/*計算長度等於bin[0]的所有二進位制數中RN的個數*/
int zero=0; //從高位向低位搜尋過程中出現0的位的個數
for(i=bin[0]-1;i>=1;i--)
if(bin[i]) //當前位為1
for(j=(bin[0]+1)/2-(zero+1);j<=i-1;j++)
sum+=c[i-1][j];
else
zero++;
return sum;
}
int main(void)
{
play_table();
int a,b;
cin>>a>>b;
cout<<round(b+1)-round(a)<<endl;
return 0;
}
必須的大神,這個題想了兩天了,知道和數學有關係,就是沒想出來怎麼做,去搜了部落格,大神解釋的很清楚,每一步都很到位,我不懂得地方大神都有講解,比如for迴圈裡面的開始結束條件,必須的聰明啊,大神就是厲害,膜拜中。。。。第一次轉載部落格,不太會弄,不好的地方多多見諒,反正都已經不好了,你也打不到我是不是,淡定。
繼續學習!
相關推薦
Round Numbers--楊輝三角,組合數學
大致題意: 輸入兩個十進位制正整數a和b,求閉區間 [a ,b] 內有多少個Round number 所謂的Round Number就是把一個十進位制數轉換為一個無符號二進位制數,若該二進位制數中0的個數大於等於1的個數,則它就是一個Round Number 注意,轉換所得的二進位制數,最高位必然是1,最
Combinatorics——HDUOJ 1799 - 迴圈多少次?(楊輝三角 - 排列組合)
原題: Problem Description 我們知道,在程式設計中,我們時常需要考慮到時間複雜度,特別是對於迴圈的部分。例如, 如果程式碼中出現 for( i=1; i<=n; i++) OP ; 那麼做了n次OP運算,如果程式
初夏小談:判斷運動員名次,楊輝三角,日本謀殺案(斷案大師)
今天給大家帶來三道經典題型。 5位運動員參加了10米臺跳水比賽,有人讓他們預測比賽結果 A選手說:B第二,我第三; B選手說:我第二,E第四; C選手說:我第一,D第二; D選手說:C最後,我第三; E選手說:我第四,A第一; 比賽結束後,每位選手都說對了一半,請程式設計確定比賽的名次。 #
藍橋杯(java):數列特徵,查詢整數,楊輝三角,特殊的數字,迴文數
人生無趣,生活不易,一起找點樂子吧。 數列特徵: 問題描述 給出n個數,找出這n個數的最大值,最小值,和。 輸入格式 第一行為整數n,表示數的個數。 第二行有n個數,為給定的n個數,每個數的絕對值都小於10000。 輸出格式 輸出三行,每行一個整
Python實現楊輝三角,超詳細!
巧妙實現楊輝三角程式碼 def triangles(): N=[1] #初始化為[1],楊輝三角的每一行為一個list while True: yield N #yield 實現記錄功能,沒有下一個next將跳出迴圈, S=N[:] #將l
利用楊輝三角求組合程式碼
//在資料型別內運算可以求得正確結果,程式碼有冗餘,由三角矩陣的兩列可以得出全部組合數列,暫時先用這種笨拙的方法 #include <iostream> using namespace std; int main(int argc, char* argv) {
控制檯列印N行楊輝三角,並算出總和
Scanner src = new Scanner(System.in);System.out.println("請輸入楊輝三角的行數: ");int total = 0;int total1 = 0;int a =src.nextInt();//定義一個二維陣列int[]
poj 3252 Round Numbers (楊輝三角求組合數)
題目連結:poj 3252 題意:給出範圍為 [a , b] 的區間,問在這區間內的每個數字,假如它的二進位制位0的個數大於1的個數,就說明它是Round Numbers,問你有多少個Round Numbers數? 題解:首先楊輝三角求組合數學,見程式碼。 ///此
Codeforces Round #439 (Div. 2)(補題) A模擬+set B 數學 C dp or 楊輝三角組合數
— This is not playing but duty as allies of justice, Nii-chan! — Not allies but justice itself, Onii-chan! With hands joined, go everywhere at a speed fas
求第n行楊輝三角(n很大,取模
int 為什麽不能 style code 為我 max sin clas pan 1 #include <iostream> 2 #include <cstdio> 3 4 using namespace std; 5 typedef
Java小題,通過JNI調用本地C++共享庫中的對應方法實現楊輝三角的繪制
question 文件夾 path ron variable iostream ring printf spl 1.在Eclipse中配置Javah,配置如下 位置是你javah.exe在你電腦磁盤上的路徑 位置:C:\Program Files\Java\jdk1.
列表, 元組,以及字符串等字符結構以及楊輝三角的四種寫法
and part ascii碼 sha collect sci 有一個 第一個 [] 列表的 刪除復制等操作: list.remove(value) 刪除遇到的第一個值 list.pop(index)就地彈出某個值
*【CodeForces - 214D 】Numbers (dp,組合數學)
題幹: Furik loves writing all sorts of problems, especially such that he can't solve himself. You've got one of his problems, the one Furik gave to
楊輝三角的新的演算法,Java初級
楊輝三角可以說是比較常見的程式問題,他的描述如下 楊輝三角形又稱Pascal三角形,它的第i+1行是(a+b)i的展開式的係數。 它的一個重要性質是:三角形中的每個數字等於它兩肩上的數字相加。 簡單的說就是他的每一行的第一個和最後一個等於1;中間的等於他的上以行的一個加上
帶有技巧的搜尋(洛谷,數獨二進位制優先找列舉順序,旅行商(寫了狀壓DP),數字三角(利用楊輝三角的係數),滑雪(記憶化))
ACM題集:https://blog.csdn.net/weixin_39778570/article/details/83187443 P1118 [USACO06FEB]數字三角形Backward Digit Su… 題目:https://www.luogu.org/problemn
編碼輸出圖形的思想:最重要的不是怎麼敲,而是怎麼想!(楊輝三角和輸出金字塔!)
我們在程式設計練習初始階段總會碰到這樣的演算法題,輸出一個怎樣怎樣的圖形,達到什麼樣的效果,其實這樣的題都會有一個固定的思想。 首先要發現其中隱藏的規律,既然是輸出圖形,怎麼擺放一定是有規律的,要不然各種亂,一點規律沒有,這樣的題就一點意義都沒有了。所以拿到這種演算法題,
二維陣列空指標,列印楊輝三角
需求:輸出楊輝三角 錯誤程式碼: import java.util.Scanner; class arraydemo3{ public static void main(String[] args){ Scanner sc = new Scanner(System.in); Syst
楊輝三角:非常容易理解的一種方式,採用前面新增空格的形式實現對稱
package javacore; /** * @author lixw * @date created in 14:54 2018/12/17 */ public class Test02 { public static void main(String[] args) {
Recursive sequence 矩陣快速冪 + 組合數 非線性變線性,利用到了組合數(楊輝三角求解快)
Farmer John likes to play mathematics games with his N cows. Recently, they are attracted by recursive sequences. In each turn, the cows would stand in a
輸出楊輝三角的前m行,生成器的應用
m = int(input('請輸入行數:')) def triangles(): L = [1] while len(L) < = m: yield L