C解法
如果当前数字是偶数,可以将其除以 2。
如果当前数字是奇数,可以加 1 或减 1。
由于问题的目标是求最小步数,这个问题适合使用 广度优先搜索(BFS) 来解决。BFS 能够保证找到从 n 到 1 的最短路径,因为它会按层次遍历所有可能的状态,确保我们在找到 1 时,是通过最少的步骤到达的。
BFS 思路
队列:使用队列来维护当前的状态,每个队列元素包含两个信息:当前数字和到达该数字的步数。
集合:为了防止重复计算,使用一个集合(或者类似的机制)来记录已经访问过的数字。
初始状态:将初始数字 n 和步数 0 入队。
状态转移:对于当前数字:
如果是偶数,将其除以 2 并入队。
如果是奇数,尝试加 1 或减 1,并将结果入队。
终止条件:一旦队列中出现 1,返回当前的步数
#include
#include
#include
#define QUEUE_SIZE 1000000
typedef struct {
long long num;
int steps;
} State;
typedef struct {
State data[QUEUE_SIZE];
int front;
int rear;
} Queue;
void enqueue(Queue* q, State value) {
if ((q->rear + 1) % QUEUE_SIZE == q->front) {
return;
}
q->data[q->rear] = value;
q->rear = (q->rear + 1) % QUEUE_SIZE;
}
State dequeue(Queue* q) {
State value = q->data[q->front];
q->front = (q->front + 1) % QUEUE_SIZE;
return value;
}
int is_empty(Queue* q) {
return q->front == q->rear;
}
int main() {
long long num;
scanf("%lld", &num);
if (num == 1) {
printf("0\n");
return 0;
}
Queue q = { .front = 0, .rear = 0 };
enqueue(&q, (State) { num, 0 });
while (!is_empty(&q)) {
State current = dequeue(&q);
long long n = current.num;
int steps = current.steps;
if (n == 1) {
printf("%d\n", steps);
return 0;
}
if (n % 2 == 0) {
enqueue(&q, (State) { n / 2, steps + 1 });
}
else {
enqueue(&q, (State) { n + 1, steps + 1 });
enqueue(&q, (State) { n - 1, steps + 1 });
}
}
return 0;
}
class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
评论记录:
回复评论: