• 蓝桥杯算法训练-数组移动


    蓝桥杯算法训练题解
    更好的阅读体验

    题目描述

    初始数组A[N]中为1,2,…,N,N个数字,现要进行M次操作,每次操作给定一个数字i,记其在数组中的位置为Bi,将A[1]…A[Bi]移到数组末尾。

    题解

    • 首先,需要认清这个移动其实是一个循环右移的过程
    • 其次,要知道循环右移是可以累计的,比如第一次右移了b1位,第二次右移了b2位,那么数字x对应的下标就会变成 ( x − 1 + b 2 + b 2 ) m o d    n (x - 1 + b2 + b2) \mod n (x1+b2+b2)modn,也就是 ( x − 1 + t o t a l ) m o d    n (x - 1 + total) \mod n (x1+total)modn, total是每次右移的总和。这样就可以在 O ( 1 ) O(1) O(1)时间复杂度内求出x对应的坐标是多少了。
    • 最后,只需要知道每一次右移多少位就行了,可以发现,把 x x x所在的下标 b b b右移到 n − 1 n - 1 n1,右移了 ( n − b − 1 ) (n - b - 1) (nb1)位。
    • 补充,这里假设数组下标从0开始

    代码

    • java

    下面注释掉的代码是使用hash表进行处理的代码,时间复杂度 O ( n ∗ m ) O(n * m) O(nm),因为初始没有发现是循环右移操作,最后手动计算了一下才发现, 另外C++代码看着自己写吧。这么简单没有必要重写c++了。

    
    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.InputStreamReader;
    import java.io.OutputStreamWriter;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Scanner;
    
    /**
     * @author: Zekun Fu
     * @date: 2022/10/28 17:29
     * @Description:
     */
    public class Main {
    
    //    1 2 3 4 5
    //    4 5 1 2 3
    //    3 4 5 1 2
    //    之前的数字都加上了(n - Bi - 1);
    //    之后的数字都减去了(n - Bi - 1);
    //    使用ha是存储每一个数字的位置,找到这个位置,
    //    遍历hash表,之前的数字都加上n - 1 - Bi,之后的数字都减去n - 1 - Bi
    
        public static void main(String[] args) throws Exception{
            BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
            BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));
            String[] firstLine = in.readLine().split(" ");
            int n = Integer.valueOf(firstLine[0]);
            int m = Integer.parseInt(firstLine[1]);
            HashMap<Integer, Integer> mp = new HashMap<>();
            int total = 0;              // 循环右移的位数
            for (int i = 0; i < m; i++) {
                int x = Integer.valueOf(in.readLine());
                int b = (x - 1 + total) % n;      // x所在的下标b
                total += (n - 1 - b);             // 现在右移的位数
            }
    //        for (int  i = 1; i <= n; i++) mp.put(i, i - 1);
    //        for (int i = 0; i < m; i++) {
    //            int x = Integer.valueOf(in.readLine());
    //            int b = mp.get(x);
    //            for (Integer key : mp.keySet()) { // 循环右移n - i - 1位
    //                int p = mp.get(key);
    //                p = (p + n - 1 - b) % n;
    //                mp.put(key, p);
    //            }
    //        }
            int[] ans = new int[n];
            for (int i = 1; i <= n; i++) {
                int p = (i - 1 + total) % n;
                ans[p] = i;
            }
            for (int x : ans) out.write(x + " ");
            out.flush();
            out.close();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
  • 相关阅读:
    服务网格和CI/CD集成:讨论服务网格在持续集成和持续交付中的应用。
    Ubuntu 22报错:PAM unable to dlopen(pam_tally2.so)
    Linux:安装AnyConnect客户端教程
    一、uniCloud的简介
    嵌入式学习之Linux驱动(第九期_设备模型_教程更新了)_基于RK3568
    Go的error接口
    MySQL查询常见错误及其解决方法
    视频上的水印文字如何去掉?
    (2022杭电多校四)1001-Link with Bracket Sequence II(区间动态规划)
    2023第51届(郑州)全国文房四宝艺术博览会将于11月10日在郑州启幕
  • 原文地址:https://blog.csdn.net/fuzekun/article/details/127576438