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 @ 2020-10-21 19:23  洛沐辰  阅读(507)  评论(0编辑  收藏  举报