题目描述
初始数组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 (x−1+b2+b2)modn,也就是 ( x − 1 + t o t a l ) m o d n (x - 1 + total) \mod n (x−1+total)modn, total是每次右移的总和。这样就可以在 O ( 1 ) O(1) O(1)时间复杂度内求出x对应的坐标是多少了。
- 最后,只需要知道每一次右移多少位就行了,可以发现,把 x x x所在的下标 b b b右移到 n − 1 n - 1 n−1,右移了 ( n − b − 1 ) (n - b - 1) (n−b−1)位。
- 补充,这里假设数组下标从0开始
代码
- java
下面注释掉的代码是使用hash表进行处理的代码,时间复杂度 O ( n ∗ m ) O(n * m) O(n∗m),因为初始没有发现是循环右移操作,最后手动计算了一下才发现, 另外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();
}
}