我的第一个小算法~(三叉树、队列)

题目
Problem Description
Farmer John has been informed of the location of a fugitive cow and wants to catch her immediately. He starts at a point N (0 ≤ N ≤ 100,000) on a number line and the cow is at a point K (0 ≤ K ≤ 100,000) on the same number line. Farmer John has two modes of transportation: walking and teleporting.

* Walking: FJ can move from any point X to the points X - 1 or X + 1 in a single minute
* Teleporting: FJ can move from any point X to the point 2 × X in a single minute.

If the cow, unaware of its pursuit, does not move at all, how long does it take for Farmer John to retrieve it? 

 
Input

Line 1: Two space-separated integers: N and K 
Output

Line 1: The least amount of time, in minutes, it takes for Farmer John to catch the fugitive cow. 
Sample Input

5 17
Sample Output

4
Hint

The fastest way for Farmer John to reach the fugitive cow is to move along the following path: 5-10-9-18-17, which takes 4 minutes
代码

#include"stdio.h"

#include"stdlib.h"

#include"math.h"

typedef struct QNode

{

    int data;

    struct QNode *next;

} QNode,*QueuePtr;   //QNode 队列节点这儿还用了typedef的符合语法,QueuePtr也被定义为类型别名,代表队列节点指针类型;

 

typedef struct

{

    QNode*front;

    QNode*rear;

}  LinkQueue;     //定义一个句柄结构体实例,指向队列节点的头与尾

 

voidInitQueue(LinkQueue &Q)//初始化队列,使句柄结构体实例指向一个队列

{

    Q.front=(QNode*)malloc(sizeof(QNode));

    if(!Q.front) exit(-1); //-1就是EXIT_FAILURE预编译器变量

    Q.front->next=NULL;

    Q.rear=Q.front;

}

voidEnQueue(LinkQueue &Q,int e)

{

    Q.rear->next=(QNode*)malloc(sizeof(QNode));

    Q.rear=Q.rear->next;

    Q.rear->data=e;

    Q.rear->next=NULL;

}

voidDeQueue(LinkQueue &Q,int &e)

{

    if(!Q.front->next)

       ;

    else

    {

       QNode*p=Q.front->next;

       e=p->data;

       Q.front->next=p->next;

       if(p==Q.rear)

           Q.rear=Q.front;

       free(p);

    }

}

boolIsEmpty(LinkQueue Q)

{

    if(Q.front==Q.rear) 

       return true; return false;

}

intMinLength(int start,intdes)//求start到des的最短路径的长度

{

    int n=0,e;

    LinkQueueQ;

    InitQueue(Q);

    EnQueue(Q,start);

    while(!IsEmpty(Q))//其实Q永远不会为空,这个循环每次让Q指向队列的节点加

    { 

       DeQueue(Q,e);

       n++;             //每取一个元素都加,n代表循环次数,也代表当前检查到三叉

       if(e!=des)       //数的节点位置,当检查到n的时候队列中共有n+1个节点,

       {                  //虚拟的三叉树此时有n+1个节点

           EnQueue(Q,e-1);

           EnQueue(Q,e+1);

           EnQueue(Q,2*e); 

       }

/*

 

 //这后面的if else 语句是为了判定n是否恰好到了三叉树的某一层的最右边的

 //那个节点,如果是这样,那么n+1恰好是的x次幂,因为double存储有误差

 //所以如果一个double值取整跟它本身的值差e-6(或-(e-6))就当它是整数 

 //此时算出的三叉树高度比n所在的高度刚好大一,其他情况算出的高度取整就是       

 //实际值,这个地方应该先加.1再取整,保证double取到最       

 //接近的整值

*/

       else if

           (fabs((int)(log(2*n+1)/log(3))-log(2*n+1)/log(3))<1e-6|| fabs( (int)(log(2*n+1)/log(3))-log(2*n+1)/log(3))>1-1e-6)  

           return (int)(log(2*n+1)/log(3)+0.1)-1; 

       else  

           return (int)(log(2*n+1)/log(3));//

    }

}

voidmain()

{

    int start,des;

    scanf("%d%d",&start,&des);//输入起点和终点

    printf("%d",MinLength(start,des));

    ::system("pause");

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值