解题思路

本题是一个最短路径搜索问题,小易需要从初始位置通过两种移动方式到达能被1,000,000,007整除的位置。

关键点

  1. 两种移动方式:
    • 4x + 3
    • 8x + 7
  2. 限制条件:
    • 最多使用100,000次移动
    • 目标位置必须能被1,000,000,007整除
  3. 需要找到最少的移动次数

解决方案

使用BFS(广度优先搜索)来寻找最短路径:

  1. 从初始位置开始,每次尝试两种移动方式
  2. 使用取模运算避免数字溢出
  3. 记录已访问位置避免重复搜索
  4. 当找到目标位置或超过移动次数限制时停止搜索

代码

#include <iostream>
#include <queue>
#include <unordered_set>
using namespace std;

class Solution {
public:
    int solve(int x0) {
        const int MOD = 1000000007;
        const int MAX_STEPS = 100000;
        
        // 如果初始位置就能被MOD整除,直接返回0
        if (x0 % MOD == 0) return 0;
        
        // 使用集合记录已访问的位置
        unordered_set<int> visited;
        // 队列存储<位置, 步数>
        queue<pair<int, int>> q;
        
        q.push({x0, 0});
        visited.insert(x0);
        
        while (!q.empty()) {
            int pos = q.front().first;
            int steps = q.front().second;
            q.pop();
            
            if (steps >= MAX_STEPS) continue;
            
            // 尝试两种移动方式
            long long next1 = (4LL * pos + 3) % MOD;
            long long next2 = (8LL * pos + 7) % MOD;
            
            // 检查第一种移动方式
            if (next1 == 0) return steps + 1;
            if (visited.find(next1) == visited.end()) {
                visited.insert(next1);
                q.push({next1, steps + 1});
            }
            
            // 检查第二种移动方式
            if (next2 == 0) return steps + 1;
            if (visited.find(next2) == visited.end()) {
                visited.insert(next2);
                q.push({next2, steps + 1});
            }
        }
        
        return -1;
    }
};

int main() {
    int x0;
    cin >> x0;
    Solution solution;
    cout << solution.solve(x0) << endl;
    return 0;
}
import java.util.*;

public class Main {
    public static int solve(int x0) {
        final int MOD = 1000000007;
        final int MAX_STEPS = 100000;
        
        // 如果初始位置就能被MOD整除,直接返回0
        if (x0 % MOD == 0) return 0;
        
        // 使用集合记录已访问的位置
        Set<Integer> visited = new HashSet<>();
        // 队列存储<位置, 步数>
        Queue<int[]> queue = new LinkedList<>();
        
        queue.offer(new int[]{x0, 0});
        visited.add(x0);
        
        while (!queue.isEmpty()) {
            int[] current = queue.poll();
            int pos = current[0];
            int steps = current[1];
            
            if (steps >= MAX_STEPS) continue;
            
            // 尝试两种移动方式
            long next1 = (4L * pos + 3) % MOD;
            long next2 = (8L * pos + 7) % MOD;
            
            // 检查第一种移动方式
            if (next1 == 0) return steps + 1;
            if (!visited.contains((int)next1)) {
                visited.add((int)next1);
                queue.offer(new int[]{(int)next1, steps + 1});
            }
            
            // 检查第二种移动方式
            if (next2 == 0) return steps + 1;
            if (!visited.contains((int)next2)) {
                visited.add((int)next2);
                queue.offer(new int[]{(int)next2, steps + 1});
            }
        }
        
        return -1;
    }
    
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int x0 = sc.nextInt();
        System.out.println(solve(x0));
        sc.close();
    }
}
def solve(x0: int) -> int:
    MOD = 1000000007
    MAX_STEPS = 100000
    
    # 如果初始位置就能被MOD整除,直接返回0
    if x0 % MOD == 0:
        return 0
    
    # 使用集合记录已访问的位置,避免重复访问
    visited = set()
    # 队列存储(位置, 步数)
    queue = [(x0, 0)]
    visited.add(x0)
    
    while queue:
        pos, steps = queue.pop(0)
        
        if steps >= MAX_STEPS:
            continue
            
        # 尝试两种移动方式
        next_positions = [
            (4 * pos + 3) % MOD,  # 第一种移动方式
            (8 * pos + 7) % MOD   # 第二种移动方式
        ]
        
        for next_pos in next_positions:
            # 如果找到能被MOD整除的位置
            if next_pos == 0:
                return steps + 1
                
            # 如果是新位置,加入队列
            if next_pos not in visited:
                visited.add(next_pos)
                queue.append((next_pos, steps + 1))
    
    return -1

# 读取输入
x0 = int(input())
# 输出结果
print(solve(x0))

算法及复杂度

  • 算法:广度优先搜索(BFS)
  • 时间复杂度:,最坏情况下需要遍历所有可能的步数
  • 空间复杂度:,需要存储已访问的位置集合