D - 整数变换问题

Description

整数变换问题。关于整数i的变换f和g定义如下:f(i)=3i;
试设计一个算法,对于给定的2 个整数n和m,用最少的f和g变换次数将n变换为m。例如,可以将整数15用4 次变换将它变换为整数4:4=gfgg(15)。当整数n不可能变换为整数m时,算法应如何处理?
对任意给定的整数n和m,计算将整数n变换为整数m所需要的最少变换次数。

Input

输入数据的第一行有2 个正整数n和m。n≤100000,m≤1000000000。

Output

将计算出的最少变换次数以及相应的变换序列输出。第一行是最少变换次数。第2 行是相应的变换序列。

Sample

Input

15 4

Output

4
gfgg

题解:

题目有一个坑,他输出的变换序列是倒叙输出的。
题目的难点在于“剪枝”,由于题目没有明确的界限,所以用操作步数来限定遍历的深度,来达到类似“剪枝”的目的。
题目数据偏弱,不用考虑无法达到的情况。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <string>
#include <queue>
#define maxn 105

using namespace std;

/**
*n开始变化的数
*m目标值
*MAX最大操作步数
*c记录每一次操作
*/
int m, n, MAX;
char c[maxn];
/**
*return 0递归继续, 1递归结束
*/
int dfs(int step,int num){
    //如果当前操作步数超过最大操作步数,结束递归。
    if(step > MAX){
        return 0;
    }
    //如果f操作或f操作的后续能够达到目标操作,则记录,并且返回结束标志。
    if(num*3==m || dfs(step + 1, num * 3)){
        c[step - 1] = 'f';
        return 1;
    }
     //如果g操作或g操作的后续能够达到目标操作,则记录,并且返回结束标志。
    if(num / 2==m || dfs(step + 1, num / 2)){
        c[step - 1] = 'g';
        return 1;
    }
    return 0;
}

int main()
{
    int i;
    scanf("%d%d",&n,&m);
    MAX = 1;
    //最大操作步数从1开始,如果没有返回结束标志则说明当前递归深度不能达到目标值。
    //操作不是+1(递归深度+1)
    while(!dfs(1, n)){
        MAX ++;
    }
    printf("%d\n",MAX);
    for(i=MAX-1; i>=0; i--)
        printf("%c",c[i]);
    printf("\n");
    return 0;
}
posted @   洛沐辰  阅读(531)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示