大数学家高斯小时候偶然间发现一种有趣的自然数集合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的多行输入了,如果输入为真就继续去做,这样可以实现多行的输入与输出。