您的位置:首页 > 其它

UVa 3n+1 问题

2011-08-29 16:26 309 查看
《挑战编程》第一个问题3n+1 看似非常简单的问题。但如果只是简单的使用蛮力法,就是超时的结果。所以在计算一个数n,它的节数的同时。需要把它经过的数记录下来。因为这些数的节数都与n有关。在查找n的同时,可以把这些数的节数同时也找出来。 代码如下:

#include <vector>
#include <stdio.h>
#include <iostream>
using namespace std;

const int scale = 5000000;

int answer[scale + 1] = {0};
vector< unsigned int > Numvec;

// 查找num的值及其经过的数的值
void funfind( unsigned int num);
//  处理栈中的经过的数
void process();

/*
* 递归查找经过的各个数的 节数。
* 对于同一个数将不会重复查找
*
*/
void funfind(unsigned int num)
{
Numvec.push_back( num );
if ( !(num % 2) && num / 2 > scale   ) // 为偶数, 且超值了。
{
funfind( num / 2);
}
else if( !(num % 2) && num / 2 <= scale &&  answer[ num / 2 ]  )
{
Numvec.push_back( num / 2 );
process();
}
else if( !(num % 2) && num / 2 <= scale && answer[ num / 2 ] == 0  )
{
funfind( num / 2);
}
else
{
funfind( 3 * num + 1);
}

}
/*
* 处理队列中的各个数,计算其节数。
*
*/
void process( )
{
size_t vecsize = Numvec.size();
int addNumber = answer[ Numvec[ vecsize -1 ] ];

vector< unsigned int >::iterator end = Numvec.end();

for(vector<unsigned int >::iterator it = Numvec.begin();
it != end; ++ it)
{
if( (*it) < scale )
answer[ *it ] = vecsize - 1 + addNumber;
vecsize --;
}
Numvec.clear();
}

int main( int argc, char ** argv)
{
int low , high;
int max = 0;
int pos = 0 ;
answer[1] = 1;
answer[2] = 2;

while( scanf("%d %d",&low, &high ) != EOF  )
{
max = 0;

cout << low << " " << high << " ";
if( low > high )
{
int temp = low;
low = high;
high = temp;
}
for(int i = low; i <= high; ++i )
{
if(!( answer[i] ) )
funfind(i);
if ( max < answer[i] )
{
max = answer[i];
pos = i;
}
}
cout  << max << endl;
}
return 0;
}


这个题目提醒我们,应该考虑较多的是时间复杂度。毕竟现在的计算机的内存都是非常大的。我们编写的程序如果只是多占用几MB或十几MB,却能大大的降低时间复杂度,这又何乐不为。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: