版权声明:转载标明出处即可 https://blog.csdn.net/hpu2022/article/details/84108361
先来看我的第一种思路
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 1000000 + 7;
int Q[MAXN * 2 + 2];
int arr[MAXN * 2 + 2];
int main()
{
int a, n;
while(cin >> a >> n)
{
Q[0] = a;
for(int i=0; i<=n; i++)
{
Q[i*2+1] = Q[i] * 2 + 1; // 左子树
Q[i*2+2] = Q[i] * 3 + 1; // 右子树
}
sort(Q, Q+ n*2+3); // 排序
int cnt = 0;
arr[0] = Q[0];
for(int i=0; i<=n*2 +2; i++) // 去重
{
if(arr[cnt] != Q[i])
arr[++cnt] = Q[i];
}
cout << arr[n-1] << endl; // 输出第n个元素
}
return 0;
}
第一种思路是建立一个二叉树,因为每个节点都会衍生出另外两个结点,分别是2x+1 和 3x+1,这符合二叉树的特性
因此建立的是一个线性的二叉树
根节点 Q[0]
左子树 i * 2 + 1 右子树 i * 2 + 2
因为这样建立起来,线性数组中并不是升序排列
所以sort排序一下
此外在建立的过程中可能有相同值的结点,所以在排序后需要去重。
这些都完成后,去重后的数组中第 n - 1 个元素,就是要输出的第 n 个值。
但是,这样做并不对,当测试数据较小的时候是没问题的,当测试数据较大是就会出现实际输出的值比理论值大的情况。
至于BUG在哪里我暂时还没有发现。
接下来是另一个思路,直接看代码吧,有详细注释。
#include <iostream>
using namespace std;
const int MAXN = (int) 1e6 + 7;
int Q[MAXN];
int main()
{
int a, n;
int two, three, rear;
while(cin >> a >> n)
{
Q[0] = a; // 基
two = three = rear = 0; // 初始下标为0
int tmp, tmp1, tmp2;
while(rear < n)
{
// 分析:
// 从第一个数开始,每个数都会衍生出两个数,分别是 2x+1 和 3x+1
// 我们不是每次都把同一个数衍生出的两个数都求出来
// 而是错开
// 即可以不同时的取最多两个数中的一个 2x+1 另一个取 3x+1
// 每次取这两者中较小的一个
// 然后较小的这个数的原型 x 就的一个衍生数 2x+1 或 3x+1 就已经取过了
// 所以就会有 two++ 或 three++
tmp1 = Q[two] * 2 + 1;
tmp2 = Q[three] * 3 + 1;
tmp = min(tmp1, tmp2); // 取较小的一个
tmp1 < tmp2 ? two ++ : three ++;
if(Q[rear] != tmp) // 不是重复出现的元素就加入
Q[++rear] = tmp;
}
cout << Q[n-1] << endl;
}
return 0;
}