HDU1032 The 3n + 1 problem循环次数

HDU1032 The 3n + 1 problem

#include<iostream>
using namespace std;
int main(){
    int n,cnt;
    cin>>n;
    for(cnt=0;n!=1;cnt++){
        if(n%2)n=3*n+1;
        else n=n/2;
    }
    cout<<cnt+1;//"cycle length"
}

题意:对n做上面代码的循环,直到n变成1,这个过程中n变成了多少个数,比如:n=22时循环中n的值依次为22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1,共有16个数,所以”cycle length”=16,其实就是循环次数+1啦。
现在给了一个区间[ i , j ],区间内每一个数都有一个”cycle length”,求最大”cycle length”是多少。

思路:如果对每个区间的每个数都硬生生的去求”cycle length”的话肯定会超时,应该用一个数组保存计算过的值,一是避免重复计算,二是在计算时当n变成了已经保存过的值,就可以直接拿来使用,不必再计算一遍

AC代码:

#include<iostream>
#include<cstdio>
using namespace std;
#define N 1000000
int a[N]={0};//记录n的"cycle length"
int i,j;
int work(){//边计算边打表
    int max=0;
    for(int x=i;x<=j;x++){
        if(a[x]==0){//如果没有被计算过才进来计算
            int n=x;
            for(int cnt=0;;cnt++){
                if(n<N&&a[n]){a[x]=a[n]+cnt;break;}//计算过程中如果发现n被计算过,加起来就跳出
                if(n%2)n=3*n+1;
                else n=n/2;
            }
        }
        if(a[x]>max)max=a[x];//记录[i,j]内最大值
    }
    return max;
}
int main(){
    a[1]=1;//需要一个初始值
    while(scanf("%d%d",&i,&j)!=EOF){
        printf("%d %d ",i,j);
        if(i>j)swap(i,j);//题目没说i,j大小关系
        printf("%d\n",work());
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值