整数变换问题
题意:问我们最少经过多少次变换可以将n转化为m。
题解:这个题我们很容易想到就是用dfs,但是数据范围也很明显不能用直接的暴力,所以我们需要剪枝。
我们假设用最原始的暴力,就是每次循环两种情况一直到最后。这样的暴力很机械,很盲目,我们必须找到所有的情况才能结束,因为只有所有的情况都出现了,我们才能判断出最少的步数是多少。但是如果我们先确定步数,也就是让这个代码走那么多步,看能否达到预定的情况,这样我们就少走了那些,这样是要优于纯暴力的。
下面是具体的代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
char s[200];
int len;//字符数组的长度
int maxsum;//所走的最大步数
int cal(int i,int n)
{
if(i==0)
return 3*n;
else
return n/2;
}
int dfs(int step,int n,int m)
{
if(step>maxsum)
return 0;
for(int i=0;i<2;i++)
{
int num=cal(i,n);
if(num==m||dfs(step+1,num,m))//dfs返回1说明匹配到n==m
{
if(i==0)
{
s[len++]='f';
}
else
{
s[len++]='g';
}
return 1;
}
}
return 0;
}
int main()
{
int n,m;
cin>>n>>m;
len=0;
maxsum=1;
while(!dfs(1,n,m))//达到剪枝效果
{
maxsum++;
}
cout<<maxsum<<endl;
for(int i=0;i<len;i++)
{
cout<<s[i];
}
cout<<endl;
return 0;
}
代码中的maxsum就是为了剪枝,我们判断当前的步数能否达到最终结果,这样假设能达到的话就直接推出while循环了。这样就大大减少了走的步数。