题意
给两个数a,b。问经由乘2和乘10加1这两种变化,是否能得到数b?很简单?不要被事物的表面现象所迷惑!! 好吧对于部分人来说的确很简单。。。
思路
一开始用的纯dfs,但是发现不会记忆路径。后来发现(看见别人的)能用逆向思维来解,就增加了一步求一可行解的函数,可能有点四不像吧。
运用dfs时要注意定义的数据类型的大小,如果是int 则会溢出,应该用__int64。还有就是队列里把大于b的数给剔除掉,这样才有dfs结束的时候。
code
#include<queue>
#include<stdio.h>
using namespace std; //怎么记忆路径???
//呵呵。。用了之前学的dfs 队列的思想还有print里的是看了别人写的
int dfs(__int64 a,__int64 b)// emmm。。 先判断是否能转化,再来输出一组可行解 感觉这代码有点‘四不像’
{ //有要注意的地方是第14行的,还有是用__int64数据类型来定义如果不的话会超内存。
queue<__int64> q;
q.push(a);
while(!q.empty())
{
if(q.front()>b) //对大于b的队列元素弹出。
{
q.pop();
continue;
}
__int64 node;
node=q.front();
q.pop();
if(node==b)
return 1;
for(int i=1;i<=2;i++)
{
__int64 Node;
Node=node;
if(i==1)
{
Node=node*2;
q.push(Node);
}
else
{
Node=node*10+1;
q.push(Node);
}
}
}
return -1;
}
void print(__int64 a,__int64 b)
{
__int64 path[1000];
int t=0;
path[t++]=b;
while(b>a)
{
if((b-1)%10==0)
{
path[t]=(b-1)/10;
b=(b-1)/10;
t++;
}
else if(b%2==0)
{
path[t]=b/2;
b=b/2;
t++;
}
}
printf("%d\n",t);
for(int i=t-1;i>=0;i--)
{
printf("%I64d",path[i]);
if(i!=0)
printf(" ");
}
printf("\n");
}
int main()
{
__int64 a,b;
while(scanf("%I64d%I64d",&a,&b)!=EOF)
{
int t;
t=dfs(a,b);
if(t==1)
{
printf("YES\n");
print(a,b);
}
else
{
printf("NO\n");
}
}
return 0;
}