题目本身并不困难,但题设有很多需要考虑的地方
人类都明白用散列映射两个数组可解此题的基本算法(下附代码)
输入的数据n并非只在100左右出现而是可能为一个较大数
3*n+1这个操作会有可能出现多步运算,所得结果x最终可以大于2000,故散列表不能很小,段错误的原因一般发生于此处,通过注释代码的特定位置可以通过反馈判定此处代码是否有误
以上
#include<bits/stdc++.h>
using namespace std;
bool marked[3360], in[105];//散列表marked最小为3360
void solve(int n)
{
if(n != 2)
{if( n%2 == 0)
{
solve(n/2);
marked[n/2] = true;
}
else
{
solve((3*n + 1)/2);
marked[(3*n + 1)/2] = true;
}}
else return;
}
typedef struct Node
{
Node(int n)
{
val = n;
}
Node* next = NULL;
int val = 0;
}Node;
class insert_list
{
Node* First = NULL;
public:
insert_list()
{
}
void add(int n)
{
Node* tem = new Node(n);
if(First == NULL) First = tem;
else
{
Node * now = First , *pre = NULL;
while (now != NULL)
{
if(now->val <= tem->val && pre == NULL)
{
First = tem;
tem->next = now;
break;
}
else if(now->next == NULL)
{
now->next = tem;
break;
}
else if(now->val >= tem->val && now->next->val <= tem->val)
{
tem->next = now->next;
now->next = tem;
break;
}
pre = now;
now = now->next;
}
}
}
void print()
{
Node *now = First;
while (now!=NULL)
{
if(now->next != NULL)
cout<<now->val<<" ";
else
cout<<now->val;
now = now->next;
}
}
};
int main()
{
class insert_list * p = new insert_list();
int n = 0;
cin>>n;
int tem[n];
for(int i = 0; i <n; i++)
{
cin>>tem[i];
in[tem[i]] = true;
solve(tem[i]);
}
for(int i = 0; i < n; i++)
{
if(in[tem[i]] && !marked[tem[i]])
p->add(tem[i]);
}
p->print();
return 0;
}