求3n+1问题地解决办法

yanglight 2005-03-19 09:43:24
以下是问题的描述:

考虑一下数列的生成办法.由n开始. 如果 n是偶数除以2. 如果是奇数, 除以3加1. 这样产生一个新的n, 长此以往,直到n = 1. 例如 n = 22:

22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
历史证明:0~1000 000无所例外
求这样的数列的长度.例如对于22的数的长度是16。

程序要求:
输入m,n求[m,n]之间的所有数中的最长的长度输出
特别要求:时间短

Sample Input
1 10
100 200
201 210
900 1000



Sample Output
1 10 20
100 200 125
201 210 89
900 1000 174

...全文
657 31 打赏 收藏 转发到动态 举报
写回复
用AI写文章
31 条回复
切换为时间正序
请发表友善的回复…
发表回复
yanglight 2005-03-21
  • 打赏
  • 举报
回复
楼上的同志好啊,的确是acm的题
zengwujun 2005-03-21
  • 打赏
  • 举报
回复
在程序设计之前,必须进行数学上的优化。
yanglight 2005-03-21
  • 打赏
  • 举报
回复
re:
到113383就不行了,这个数好像不满足规律。如果只有10W左右的数,用楼主的方法就可以了

我找到错了,其中的数据类型必须是long
zengwujun 2005-03-20
  • 打赏
  • 举报
回复
乘法运算改移位,速度会快一些
yanglight 2005-03-20
  • 打赏
  • 举报
回复
re:
学习中...........
我把原程序拷贝进去运行 怎么有问题??????????

可用Dev C++编译运行
flying_dancing 2005-03-20
  • 打赏
  • 举报
回复
学习中...........
我把原程序拷贝进去运行 怎么有问题??????????
tianhxk 2005-03-20
  • 打赏
  • 举报
回复
acm /uva上面的题目,忘记怎么做出来的,好像是穷举出来的
Mc_king 2005-03-20
  • 打赏
  • 举报
回复
resultmax=(result<maxresult)?maxresult:result;

Mc_king 2005-03-20
  • 打赏
  • 举报
回复
`````这样都超时递归机器会爆炸``````````````
fengyun2 2005-03-20
  • 打赏
  • 举报
回复
呵呵 有意思呢
vc_devc 2005-03-20
  • 打赏
  • 举报
回复
int Produce(int seed)
{
int n = seed;
int cnt = 0;
printf("%d\n",seed);
while(n != 1)
{
if(!(n%2))
n >>= 1;
else
n += (n << 1) + 1;
printf("%3d\t",n);
cnt++;
}
printf("\n");
return cnt;
}

void Test(int down, int up)
{
if(down <= 1)
return ;
if(up <= 1)
return ;
if(up < down)
{
int tmp = up;
up = down;
down = tmp;
}
int max = 0;
int t;
while(up >= down)
{
t = Produce(down++);
if(max < t)max = t;
}
printf(".................\n%d\n",max);
}
int main(int argc,char *argv[])
{
Test(21,23);
return 0;
}
sanfrey 2005-03-20
  • 打赏
  • 举报
回复
到113383就不行了,这个数好像不满足规律。如果只有10W左右的数,用楼主的方法就可以了
inlin 2005-03-20
  • 打赏
  • 举报
回复
递推,但会超时,计算太多了!
llmsn 2005-03-20
  • 打赏
  • 举报
回复
学习.
rocklabzhang 2005-03-20
  • 打赏
  • 举报
回复
我的超过100000时,就会超时自动跳出:

#include<stdlib.h>

int iCount = 1; //记录总次数
void find( long t )
{
if( t == 1 )
return;
else
{
if( t%2 == 0 )
find( t/2 );
else
find( 3*t + 1 );

iCount++;
}
}

int main()
{
long m, n;
printf( "please input two number:" );
scanf( "%d %d", &m, &n );
long i;
int Temp = 0;
for( i = m; i <= n; i++ )
{
//Temp = iCount;
find( i );
Temp = iCount > Temp?iCount:Temp;
iCount = 1;
}
printf( "the max is %-5d", Temp );
system("pause");
}
zengwujun 2005-03-20
  • 打赏
  • 举报
回复
学习
sanfrey 2005-03-20
  • 打赏
  • 举报
回复
可以到10W了

#include <stdio.h>
main()
{
int min = 1, max = 100000;
int count, result = 1;
int i, n, len;
int * p;

len = max - min + 1;
p = (int*)malloc(sizeof(int) * len);

for (i = 0; i < len; i++) p[i] = min++;

i = 0;
while (len-- && (n = p[i++]))
{
count = 1;
while (n != 1)
{
if (n % 2)
n = 3 * n + 1;
else
n = n / 2;

if (n != 1 && n >= min && n <= max && p[n - min]) p[n - min] = 0;
count++;
}
if (count > result) result = count;
}
free(p);
printf("%d\n", result);
}
sanfrey 2005-03-20
  • 打赏
  • 举报
回复
吃了饭用数组来写一个,肯定比上个快得多,呵呵
sanfrey 2005-03-20
  • 打赏
  • 举报
回复
用线性链表做了一个,1-10000还可以忍受,再多就不行了,主要是搜索结点费时,如果用平衡二叉树那存那些树,查找就快多了。

#include <stdio.h>

struct node
{
int data;
struct node *next;
};

struct node * initlink(int min, int max);
void rmnode(int *min, int *max, struct node *p, int data);

main()
{
int min = 1, max = 10000;
int count, result = 1;
int n;

struct node *head = initlink(min,max);

struct node *p = head->next;

while (p != NULL)
{
n = p->data;
count = 1;
while (n != 1)
{
if (n % 2)
n = 3 * n + 1;
else
n = n / 2;

if (n != 1 && n >= min && n <= max) rmnode(&min, &max, p, n);
count++;
}
if (count > result) result = count;
p = p->next;
}
printf("%d\n", result);

}

struct node * initlink(int min, int max)
{

int len = max - min + 1;
struct node *head = NULL;

head = (struct node*)malloc(sizeof(struct node));
head->data = -1;
head->next = NULL;

while (len--)
{
struct node *m = (struct node*)malloc(sizeof(struct node));
m->data = max--;
m->next = head->next;
head->next = m;
}
return head;
}

void rmnode(int *min, int *max, struct node *p, int data)
{
struct node *r;
while(p->next)
{
r = p->next;
if(r->data != data)
p = p->next;
else
{
if (r->next && *min == data) *min = r->next->data;
if (*max == data) *max = p->data;
p->next = r->next;
free(r);
break;
}
}
}
pcboyxhy 2005-03-20
  • 打赏
  • 举报
回复
递推的确是个不错办法
加载更多回复(11)

3,881

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 其它技术问题
社区管理员
  • 其它技术问题社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧