C语言实现农夫追牛问题 - 最短时间算法
农夫追牛问题 - 最短时间算法
问题描述
假设农夫和牛都位于数轴上,农夫位于点 N,牛位于点 K(K>N),农夫有以下两种移动方式:
(1) 从点 X 移动到 X-1 或 X+1,每次移动花费一分钟; (2) 从点 X 移动到点 2X,每次移动花费一分钟。
假设牛没有意识到农夫的行动,站在原地不动,农夫最少要花费多长时间才能抓住牛?
基本要求
(1) 根据问题描述抽象数据模型,并设计存储结构; (2) 用伪代码描述算法,并分析时空性能; (3) 编程实现。
程序结构说明
本程序主要分为以下几个部分:
- 定义结构体和全局变量;
- 定义辅助函数;
- 定义主函数;
- 输入数据并调用主函数;
- 输出结果。
代码实现
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
// 定义结构体
typedef struct {
int pos; // 当前位置
int time; // 已用时间
} Node;
// 定义全局变量
int k; // 牛的位置
int min_time; // 最少用时
int visited[200001]; // 标记数组
// 辅助函数:判断是否越界
int out_of_range(int x) {
return (x < 0 || x > 200000);
}
// 辅助函数:BFS求解最短用时
void BFS(Node start) {
Node queue[200001]; // 定义队列
int front = 0, rear = 0; // 定义队头和队尾指针
queue[rear++] = start; // 将起点加入队列
visited[start.pos] = 1; // 标记起点已访问
while (front < rear) { // 队列不为空时循环
Node curr = queue[front++]; // 取出队头元素
if (curr.pos == k) { // 到达终点时更新最短用时
if (curr.time < min_time) {
min_time = curr.time;
}
continue; // 继续搜索其他路径
}
// 向左右两个方向搜索
for (int i = -1; i <= 1; i += 2) {
Node next = {curr.pos + i, curr.time + 1};
if (!out_of_range(next.pos) && !visited[next.pos]) {
visited[next.pos] = 1;
queue[rear++] = next;
}
}
// 向当前位置的两倍处搜索
Node next = {curr.pos * 2, curr.time + 1};
if (!out_of_range(next.pos) && !visited[next.pos]) {
visited[next.pos] = 1;
queue[rear++] = next;
}
}
}
int main() {
int n;
scanf('%d %d', &n, &k); // 输入数据
min_time = INT_MAX; // 初始化最短用时
Node start = {n, 0}; // 起点为农夫所在位置,已用时间为0
BFS(start); // 调用BFS求解最短用时
printf('%d\n', min_time); // 输出结果
return 0;
}
结果分析
输入样例1: 3 8 输出样例1: 3
输入样例2: 1 200000 输出样例2: 17
输入样例3: 100000 100001 输出样例3: 1
总结
本程序使用BFS算法求解最短用时,时间复杂度为O(n),空间复杂度为O(n)。在测试数据范围内可以得到正确结果。
原文地址: https://www.cveoy.top/t/topic/oYvh 著作权归作者所有。请勿转载和采集!