当前位置: 首页 > article >正文

2025.05.22-得物春招机考真题解析-第二题

📌 点击直达笔试专栏 👉《大厂笔试突围》

💻 春秋招笔试突围在线OJ 👉 笔试突围OJ

02. 魔法书页重排

问题描述

A先生是一位魔法师,他有一本古老的魔法书,书中有 n n n 页,每页都刻有一个魔法符号。最初,第 i i i 页上刻着数字 i i i

现在A先生需要按照古老的仪式来重新排列这些魔法符号。仪式的规则是:按照从小到大的顺序,对于每个 [ 1 , n ] [1, n] [1,n] 之间的整数 x x x,将所有页码为 x x x 的倍数的页面上的魔法符号向右循环移动一位。

具体来说,如果有 k k k 个页面的页码是 x x x 的倍数,分别为 p 1 , p 2 , … , p k p_1, p_2, \ldots, p_k p1,p2,,pk(按页码从小到大排列),那么这些页面上的魔法符号会按如下方式移动: p k p_k pk 页的符号移动到 p 1 p_1 p1 页, p 1 p_1 p1 页的符号移动到 p 2 p_2 p2 页,以此类推。

请输出仪式完成后每页上的魔法符号是什么。

输入格式

第一行包含一个正整数 n n n 1 ≤ n ≤ 10 5 1 \leq n \leq 10^5 1n105),表示魔法书的页数。

输出格式

第一行包含 n n n 个整数,第 i i i 个整数表示第 i i i 页上的魔法符号。

样例输入

5
8

样例输出

5 3 2 1 4
8 7 3 5 4 2 6 1

数据范围

  • 1 ≤ n ≤ 10 5 1 \leq n \leq 10^5 1n105
样例解释说明
样例1初始状态:[1,2,3,4,5]。x=1时,所有页面循环右移:[5,1,2,3,4]。x=2时,页面2,4循环右移:[5,3,2,1,4]。x=3时,页面3循环右移:不变。x=4,5同理
样例2按照相同规则进行多轮循环移动操作

题解

这道题的关键是理解"循环右移"的概念,以及如何高效地模拟这个过程。

算法思路:

  1. 初始化数组 A [ i ] = i A[i] = i A[i]=i
  2. 对于每个 x x x 1 1 1 n n n,找出所有 x x x 的倍数位置
  3. 将这些位置上的数值进行循环右移

具体实现:

  • 对于每个 x x x,收集所有倍数位置: x , 2 x , 3 x , … x, 2x, 3x, \ldots x,2x,3x,
  • 如果只有一个位置,则无需移动
  • 否则,保存最后一个位置的值,然后从后往前依次移动

举例说明( n = 5 n=5 n=5):

  • 初始: [ 1 , 2 , 3 , 4 , 5 ] [1, 2, 3, 4, 5] [1,2,3,4,5]
  • x = 1 x=1 x=1:位置 [ 1 , 2 , 3 , 4 , 5 ] [1,2,3,4,5] [1,2,3,4,5] 循环右移 → [ 5 , 1 , 2 , 3 , 4 ] [5, 1, 2, 3, 4] [5,1,2,3,4]
  • x = 2 x=2 x=2:位置 [ 2 , 4 ] [2,4] [2,4] 循环右移 → [ 5 , 3 , 2 , 1 , 4 ] [5, 3, 2, 1, 4] [5,3,2,1,4]
  • x = 3 , 4 , 5 x=3,4,5 x=3,4,5:只有一个位置,无需移动

时间复杂度分析:对于每个 x x x,需要遍历其所有倍数,总的时间复杂度为 O ( n log ⁡ n ) O(n \log n) O(nlogn),因为 ∑ x = 1 n ⌊ n x ⌋ = O ( n log ⁡ n ) \sum_{x=1}^{n} \lfloor \frac{n}{x} \rfloor = O(n \log n) x=1nxn=O(nlogn)

参考代码

  • Python
import sys
input = lambda: sys.stdin.readline().strip()n = int(input())
a = [0] + list(range(1, n + 1))  # 1-indexed数组for x in range(1, n + 1):pos = []  # 存储x的倍数位置for j in range(x, n + 1, x):pos.append(j)if len(pos) <= 1:continue# 循环右移:最后一个元素移到第一个位置last_val = a[pos[-1]]for i in range(len(pos) - 1, 0, -1):a[pos[i]] = a[pos[i - 1]]a[pos[0]] = last_val# 输出结果(去掉第0个元素)
print(' '.join(map(str, a[1:])))
  • Cpp
#include <iostream>
#include <vector>
using namespace std;int main() {ios::sync_with_stdio(false);cin.tie(nullptr);int n;cin >> n;vector<int> a(n + 1);for (int i = 1; i <= n; i++) {a[i] = i;  // 初始化}for (int x = 1; x <= n; x++) {vector<int> pos;  // 存储x的倍数位置for (int j = x; j <= n; j += x) {pos.push_back(j);}if (pos.size() <= 1) continue;// 循环右移int last_val = a[pos.back()];for (int i = pos.size() - 1; i > 0; i--) {a[pos[i]] = a[pos[i - 1]];}a[pos[0]] = last_val;}for (int i = 1; i <= n; i++) {cout << a[i];if (i < n) cout << " ";}cout << "\n";return 0;
}
  • Java
import java.util.*;
import java.io.*;public class Main {public static void main(String[] args) throws IOException {BufferedReader br = new BufferedReader(new InputStreamReader(System.in));PrintWriter pw = new PrintWriter(System.out);int n = Integer.parseInt(br.readLine());int[] a = new int[n + 1];// 初始化数组for (int i = 1; i <= n; i++) {a[i] = i;}for (int x = 1; x <= n; x++) {List<Integer> pos = new ArrayList<>();// 收集x的倍数位置for (int j = x; j <= n; j += x) {pos.add(j);}if (pos.size() <= 1) continue;// 循环右移操作int lastVal = a[pos.get(pos.size() - 1)];for (int i = pos.size() - 1; i > 0; i--) {a[pos.get(i)] = a[pos.get(i - 1)];}a[pos.get(0)] = lastVal;}for (int i = 1; i <= n; i++) {pw.print(a[i]);if (i < n) pw.print(" ");}pw.println();pw.close();br.close();}
}

http://www.lryc.cn/news/2386766.html

相关文章:

  • ollama list模型列表获取 接口代码
  • OPC Client第5讲(wxwidgets):初始界面的事件处理;按照配置文件初始化界面的内容
  • 什么是BFC,如何触发BFC,BFC有什么特性?
  • python做题日记(9)
  • Leetcode 3557. Find Maximum Number of Non Intersecting Substrings
  • 【C++进阶篇】初识哈希
  • Spring Boot——自动配置
  • 免费轻量便携截图 录屏 OCR 翻译四合一!提升办公效率
  • 使用 Vuex 实现用户注册与登录功能
  • 进程通信(管道,共享内存实现)
  • 电池预测 | 第28讲 基于CNN-GRU的锂电池剩余寿命预测
  • 快速上手SHELL脚本常用命令
  • 【无标题】前端如何实现分页?
  • 【自然语言处理与大模型】大模型Agent四大的组件
  • 小巧高效的目录索引生成软件
  • 云原生架构设计相关原则
  • android实现使用RecyclerView详细
  • 华为云Flexus+DeepSeek征文 | Flexus X实例助力 Dify-LLM 一键部署:性能跃升与成本优化的革新实践
  • 曼昆经济学原理第九版目录
  • 数据库blog7_MySql的下载与配置准备
  • YOLOv11助力地铁机场安检!!!一键识别刀具
  • RFID工业读写器的场景化应用选型指南
  • java中的线程安全的集合
  • 单片机如何快速实现查看实时数据
  • go实现钉钉三方登录
  • YOLOv1 详解:单阶段目标检测算法的里程碑
  • 5G 核心网切换机制全解析:XN、N2 与移动性注册对比
  • 物流配送优化实战:用遗传算法破解选址难题
  • Linux 个人用户设置账号密码环境变量,四种方式
  • Three.js搭建小米SU7三维汽车实战(5)su7登场