"Algorithm Contest·Quick 300 Questions" daily question: "Hail Conjecture II"

" Algorithm Competition: 300 Quick Questions " will be published in 2024, and it is an auxiliary workbook for "Algorithm Competition" .
All questions are placed in the self-built OJ New Online Judge .
The codes are provided in C/C++, Java, and Python. The topics are mainly low-to-medium level, suitable for beginners and advanced.


" Hail Conjecture II ", link: http://oj.ecustacm.cn/problem.php?id=1744

topic description

[Title description] The hail conjecture means that for any positive integer, if it is an odd number, multiply it by 3 and add 1, if it is an even number, divide it by 2, and finally it will become 1. No counterexample has been found yet.
  For example the number 6. According to the above rules, it can become 3, 10, 5, 16, 8, 4, 2, 1, after 8 transformations.
  Now given a number n, find how many numbers exist that are transformed n times to get 1. .
【Input format】 Enter a number n (0≤n≤55).
【Output Format】 Output a number to represent the answer.
【Input sample】

样例1
0

样例2
4

样例3
8

【Example of output】

样例1
1

样例2
1

样例3
4

answer

  This question obviously uses backward calculation, and there are two situations: (1) The backward calculation of "divided by 2" is "multiplied by 2"; (2) the reverse calculation of "multiplied by 3 plus 1" is "subtracted by 1 divided by 3". At this time, it should be judged that "subtracted by 1 divided by 3" can be divided completely, and it is an odd number.
  This question is a path problem. Both DFS and BFS can be used for encoding, and DFS is simpler.
[Key points] Use BFS and DFS to solve the path problem.

C++ code

  Since there are 2 situations for each backward push, 2 DFSs are continued for each DFS in the code, so the number of transformations ans is O ( 2 n ) O(2^n)O(2n )complexity, need to use long long type.
  Note that line 6 is pruning. If 1 appears again during the backward push, it means that the backward push is invalid and returns directly.

#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 code

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 code

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)

Guess you like

Origin blog.csdn.net/weixin_43914593/article/details/131768564