《算法竞赛·快冲300题》每日一题:“冰雹猜想II”

文章介绍了《算法竞赛·快冲300题》这本书中关于冰雹猜想问题的解题思路和代码实现,提供了C++、Java和Python三种语言的代码示例,主要使用深度优先搜索(DFS)解决路径问题,讨论了问题的复杂度为O(2^n)。
摘要由CSDN通过智能技术生成

算法竞赛·快冲300题》将于2024年出版,是《算法竞赛》的辅助练习册。
所有题目放在自建的OJ New Online Judge
用C/C++、Java、Python三种语言给出代码,以中低档题为主,适合入门、进阶。


冰雹猜想II” ,链接: http://oj.ecustacm.cn/problem.php?id=1744

题目描述

【题目描述】 冰雹猜想是指对于任意一个正整数,如果它是奇数,则对它乘3加1,如果是偶数,则除以2,最终会变成1,目前仍未找到反例。
  例如数字6。按照上述规则可以变成3、10、5、16、8、4、2、1,经过8次变换。
  现在给定数字n,求存在多少个数字变换n次得到1。。
【输入格式】 输入一个数字n(0≤n≤55)。
【输出格式】 输出一个数字表示答案。
【输入样例】

样例1
0

样例2
4

样例3
8

【输出样例】

样例1
1

样例2
1

样例3
4

题解

  本题显然用倒推,有2种情况:(1)“除以2”的倒推,是“乘2”;(2)“乘3加1”的倒推,是“减1除以3”,需要注意,此时应该判断“减1除以3”能除尽,而且是奇数。
  本题是路径问题,编码用DFS和BFS都行,DFS更简单一些。
【重点】 用BFS和DFS求解路径问题。

C++代码

  由于每次倒推有2种情况,在代码中每次DFS时继续做2次DFS,所以变换次数ans是 O ( 2 n ) O(2^n) O(2n)复杂度的,需要用long long类型。
  注意第6行是剪枝,如果倒推过程中又出现了1,说明这次倒推是无效的,直接返回。

#include<bits/stdc++.h>
using namespace std;
int n;
long long ans=0;
void dfs(long long x,long long cnt){
    if(x==1 && cnt!=1)  return;          //又倒推回1,无效操作,不统计ans,直接返回
    if(cnt == n+1){                      //刚好n次,结束
        ans++;
        return;
    }
    dfs(2*x, cnt+1);                     //“除以2”的倒推:乘2
    if((x-1)%3==0 && ((x-1)/3)%2==1)     //(x-1)%3:能除尽,而且是奇数
        dfs((x-1)/3, cnt+1);             //“乘3加1”的倒推:减1除以3
}
int main(){
    cin>>n;
    dfs(1,1);
    cout<<ans;
}

Java代码

import java.util.Scanner;
public class Main {
    static int n;
    static long ans = 0;
    public static void dfs(long x, long cnt) {
        if (cnt != 1 && x <= 1) return;       //又倒推回1,无效操作,不统计ans,直接返回
        if (cnt == n + 1) {                   //刚好n次,结束
            ans++;
            return;
        }
        dfs(2 * x, cnt + 1);                                //“除以2”的倒推:乘2
        if ((x - 1) % 3 == 0 && ((x - 1) / 3) % 2 == 1)     //(x-1)%3:能除尽,而且是奇数
            dfs((x - 1) / 3, cnt + 1);                      //“乘3加1”的倒推:减1除以3
    }
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        n = scanner.nextInt();
        dfs(1, 1);
        System.out.println(ans);
    }
}

Python代码

n = int(input())
ans = 0
def dfs(x, cnt):
    global ans
    if cnt != 1 and x <= 1:  return      #又倒推回1,无效操作,不统计ans,直接返回
    if cnt == n+1:
        ans += 1
        return
    dfs(2*x, cnt+1)                           #“除以2”的倒推:乘2
    if (x-1)%3 == 0 and ((x-1)//3)%2 == 1:    # (x-1)%3:能除尽,而且是奇数
        dfs((x-1)//3, cnt+1)                  # “乘3加1”的倒推:减1除以3
dfs(1,1)
print(ans)
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

罗勇军

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值