最少步数 SDUT 3080

来源:互联网 发布:零基础学数据库 编辑:程序博客网 时间:2024/06/08 19:02

题目描述

给定一个数字n,我们可以进行3种操作,加1,减1,如果可以整除2,还可以除2,问最少多少步变换到1.

输入

 输入数据的第一行包含数字n(1<=n<=10000000)。多组输入。

输出

 计算结果。

示例输入

3

示例输出

2看到别人怎么内存的消耗有的竟然是几百KB,我的四万KB,都快MLE了,但是我干囧这个题就是BFS,就当BFS的练习吧。
#include<iostream>#include<algorithm>#include<cstdio>#include<cstring>#include<cmath>#include<queue>using namespace std;int n;struct node{    int x,step;//x代表数的变化,step代表步数的变化。} str;queue <node> q;//建立一个以node这个数据类型为节点的队列,队列名称为q;int vis[10000001];//一定不要太大也不要太小,太大会MLE的int  bfs(){    while(!q.empty())//因为是多组输入,所以需要队列清零    {        q.pop();    }    memset(vis,0,sizeof(vis));    vis[str.x]=1;//对初始步数的位置标记    q.push(str);//初始值进入队列    while(!q.empty())    {        node now=q.front();        if(now.x==1)//若队列第一个便满足条件,直接返回        {            return now.step;        }        q.pop();        for(int j=0; j<3; j++)        {            node next=now;            if(j==0)            {                next.x++;            }            if(j==1)            {                next.x--;            }            if(j==2&&next.x%2==0)            {                next.x=next.x/2;            }            ++next.step;            if(next.x==1)            {            return next.step;            }            if(next.x>=1&&next.x<=10000000&&vis[next.x]==0)//若在范围内并且没有被标记过,则被标记,进入队列            {            vis[next.x]=1;            q.push(next);            }        }    }    return 0;}int main(){    while(~scanf("%d",&n))    {    str.x=n;//赋上初始值    str.step=0;//步数清零        printf("%d\n",bfs());    }    return 0;}


0 0