你听说过角谷猜想吗?
任意的正整数,比如 5, 我们从它开始,如下规则计算:
如果是偶数,则除以2,如果是奇数,则乘以3再加1.
如此循环,最终必会得到“1” !
比如 5 的处理过程是:
5
16
8
4
2
1

一个正整数经过多少步才能变成1, 称为角谷步数。
对于5而言,步数也是5
对于1,步数为0

本题的要求是,从标准输入给定一个整数n(1<n<300)表示角谷步数
求满足这个角谷步数的最小的正整数

例如:
输入:
3
则输出:
8

输入:
4
则输出:
16

输入:
7
则输出:

3

这个题刚开始看的时候想用递归求,来倒推,来显示一下我还算是理解递归的,结果败北了。对于小数据(比如两位数)还行,对于稍大这么一点点的就严重超时,最后黔驴技穷了,还是暴力吧。

在这贴一下我的错误的递归算法,要是有哪位大神会的话还望指点一下

#include <iostream>
using namespace std;
int step,mins=99999999;
void DFS(int n,int count)
{
    if(count==step)
    {
        if(n<mins)
            mins=n;
        return;
    }
    DFS(n*2,count+1);
    if((n-1)%3==0&&((n-1)/3)%2==1&&n>=10)
        DFS((n-1)/3,count+1);
}
int main()
{
    while(cin>>step)
    {
        DFS(1,0);
        cout<<mins<<endl;
    }
    return 0;
}


暴力中对算法又有了优化,优化算法类似于记忆话搜索和哈希算法

比如说当前数是temp,如果它最后算到1的步数已经有了,那我们就不用再算了,直接加上这个步数就行了。

数据类型用long long


#include <iostream>
#include <memory.h>
using namespace std;
int main ()
{
    long long a[10005];
    memset(a,0,sizeof(a));
    int n;
    cin>>n;
    for(long long i=2;; i++)
    {
        long long temp=i,count=0;
        while(temp!=1)
        {
            if(temp<=10000&&a[temp]!=0)
            {
                count+=a[temp];
                break;
            }
            if(temp%2==0)  temp=temp/2;
            else  temp=temp*3+1;
            count++;
        }


        if(i<=10000)
            a[i]=count;
        if(count==n)
        {
            cout<<i<<endl;
            break;
        }
    }
    return 0;
}




posted on 2015-04-10 10:26  星斗万千  阅读(238)  评论(0编辑  收藏  举报