POJ 3278 Catch That Cow

题目大意:

        FJ的一头奶牛逃亡了,FJ和逃亡奶牛都位于一条一维坐标轴上,FJ的位置为N,奶牛的位置为K(0 ≤ N, K ≤ 100,000),假设奶牛不动,FJ有三种移动方式,假设FJ当前位置为X,则其下一步可以移动到X - 1、X + 1、X × 2这三种位置,每移动一次耗时1分钟。

        现只有一个测例,测例中给出N、K,要求输出FJ追到奶牛最短需要多长时间。

题目链接

注释代码:

/*            
 * Problem ID : POJ 3278 Catch That Cow 
 * Author     : Lirx.t.Una            
 * Language   : C++           
 * Run Time   : 0 ms            
 * Run Memory : 320 KB            
*/   

#include <stdio.h>

//maximum coordinate
//坐标最大值
#define	MAXCORD		100000
//用数组模拟队列(不知道怎么回事用STL就一直RE!)
//经测试的最大容量
//maxium size of queue
#define	MAXQSIZE	11693

typedef	struct {//队列中的结点
	
	int		x;//结点的坐标
	int		g;//和结点的深度,初始结点深度为0,因此深度也表示步数
} Node;

Node	q[MAXQSIZE];//queue
char	vist[MAXCORD + 1];//vist[x]表示坐标x是否被访问过(在BFS过程中)

int//由于BFS是一层一层往下搜的,所以第一个遇到的解必定是最优解!!因为层数最少(即步数最少)
bfs( int n, int k ) {
	
	int		front, back;//队列的头尾
	int		fx, cx;//father and children x,父结点和子结点的坐标
	int		cg;//children's g,子结点的深度
	
	int		i;//计数变量
	
	//队列初始化
	front = 0;
	back  = 1;
	
	(*q).x = n;//头结点初始化为n,深度默认为0,因为q是全局静态变量
	vist[n] = 1;//设为访问过
	
	while (1) {//由于可以前进或后退一步,因此无论如何都是有解的!所以用死循环了
		
		//出队列
		fx = q[front].x;
		cg = q[front++].g + 1;
		
		if ( front >= MAXQSIZE )//调整队列,放置越界,使之循环起来
			front = 0;
		
		for ( i = 1; i <= 3; i++ ) {//一共就三种走法
			
			switch (i) {
				
			case 1 : cx = fx + 1;  break;
			case 2 : cx = fx - 1;  break;
			case 3 : cx = fx << 1; break;
			}
			
			if ( cx == k )//若cx一定达到目标则直接退出
				return cg;
			
			if ( !vist[cx] && cx >= 0 && cx <= MAXCORD ) {//剪枝!
				//将访问过的和超过坐标范围的都剪去
				
				//之后入队
				vist[cx]  = 1;
				q[back].x = cx;
				q[back].g = cg;
				back++;
				
				if ( back >= MAXQSIZE )//防止越界,使之循环
					back = 0;
			}
		}
	}
}

int
main() {
	
	int		n, k;//FJ和奶牛的位置
	
	scanf("%d%d", &n, &k);
	
	if ( n == k ) {//考虑特殊情况1!!
		
		puts("0");
		return 0;
	}
	
	if ( n > k ) {//特殊情况2!!由于后退的走法只有一种,因此一直后退就是
		//最快的走法
		
		printf("%d\n", n - k);
		return 0;
	}
	
	printf("%d\n", bfs( n, k ));
	return 0;
}

无注释代码:

#include <stdio.h>

#define	MAXCORD		100000
#define	MAXQSIZE	11693

typedef	struct {
	
	int		x;
	int		g;
} Node;

Node	q[MAXQSIZE];
char	vist[MAXCORD + 1];

int
bfs( int n, int k ) {
	
	int		front, back;
	int		fx, cx;
	int		cg;
	
	int		i;
	
	front = 0;
	back  = 1;
	
	(*q).x = n;
	vist[n] = 1;
	
	while (1) {
		
		fx = q[front].x;
		cg = q[front++].g + 1;
		
		if ( front >= MAXQSIZE )
			front = 0;
		
		for ( i = 1; i <= 3; i++ ) {
			
			switch (i) {
				
			case 1 : cx = fx + 1;  break;
			case 2 : cx = fx - 1;  break;
			case 3 : cx = fx << 1; break;
			}
			
			if ( cx == k )
				return cg;
			
			if ( !vist[cx] && cx >= 0 && cx <= MAXCORD ) {
				
				vist[cx]  = 1;
				q[back].x = cx;
				q[back].g = cg;
				back++;
				
				if ( back >= MAXQSIZE )
					back = 0;
			}
		}
	}
}

int
main() {
	
	int		n, k;
	
	scanf("%d%d", &n, &k);
	
	if ( n == k ) {
		
		puts("0");
		return 0;
	}
	
	if ( n > k ) {
		
		printf("%d\n", n - k);
		return 0;
	}
	
	printf("%d\n", bfs( n, k ));
	return 0;
}

单词解释:

fugitive:adj, 逃亡的

teleport:vt, 心灵运输

retrieve:vt, 重新找回

silver:n, 银,银器

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值