题目大意:
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, 银,银器