大數學家高斯小時候偶然間發現一種有趣的自然數集合Blah,對於以a為基的集合Ba定義如下:
(1) a是集合Ba的基,且a是Ba的第一個元素;
(2)如果x在集合Ba中,則2x+1和3x+1也都在集合Ba中;
(3)沒有其他元素在集合Ba中了。
現在小高斯想知道如果將集合Ba中元素按照升序排列,第N個元素會是多少?
輸入輸入包括很多行,每行輸入包括兩個數字,集合的基a(1<=a<=50))以及所求元素序號n(1<=n<=1000000)輸出對於每
個輸入,輸出集合Ba的第n個元素值樣例輸入
1 100 28 5437
樣例輸出
418 900585
#include <iostream> #include <algorithm> using namespace std; const int N=1000050; long long q[N]; int a,n; void Blah(int a,int n) { q[1]=a; int two=1,three=1,rear=2; while (rear<=n) { long long t1=q[two]*2+1,t2=q[three]*3+1; int t=min(t1,t2); t1<t2?two++:three++; if(t==q[rear-1]) continue; q[rear++]=t; } cout<<q[n]<<endl; } int main() { while(cin>>a>>n) { Blah(a,n); } return 0; }
對於這個Blah數組,其實可以將兩個算術表達式拆除出來單獨看。就僅僅把它看作一個結果,然后題目的要求可以這樣理解,給一個首元
素,然后比較表達式的大小,然后按照升序寫入這個隊列。
因為這個隊列本身並不是有序的,並不知道后面有沒有比前面小的,但是我們知道前面的數要比后面的小,然后經過表達式運算出來的結果
一定要比前面的基數要大,即使是比較,比較的也是經過計算后的數字大小。
關於這個算法就是這樣實現的,它並不是寫入,后比較,它是先算出,經比較,后寫入,因為這是一個隊列問題嘛。它就像一個碾壓式的算
法,即使現在不算,但是以后必定會算,因為變量two和three 的大小會影響到t1和t2的大小。
其中的三目運算符,理解是:t1大於t2,two++,小於則three++。這很好理解,因為與two有關的表達式是2*,與three有關的表達式是3*,
如果t1小,就增加自變量two來改變它本身的大小,所以這里就有着一種碾壓式算法的味道,每個數我都會算,即使看起來,並不是這樣。
two和three都會按照一不斷地增加的。
至於其他的,唯一好講的就是while的多行輸入了,如果輸入為真就繼續去做,這樣可以實現多行的輸入與輸出。