蓝桥杯算法题解持续更新,欢迎订阅收藏。
更好的观看效果,别忘了收藏网站哟。
题目描述
问题描述
给定一个n长的数列,有m次操作,第i次操作表示将整个数列循环移动mi位,询问每次操作结束后的开头k个数字
题解
很明显的取余操作,当前的起始坐标为cur,那么左移x,相当于 ( c u r + x ) m o d n (cur + x) \mod n (cur+x)modn作为起始坐标。右移x(x > 0),相当于 ( c u r − x ) m o d n (cur - x) \mod n (cur−x)modn,但是题目中右移,是负数,所以两个就可以合并为 ( c u r + x ) m o d n (cur + x) \mod n (cur+x)modn。
本题目有三个注意点:
-
没有给数组中数字的范围,是否使用int来保存?
-
每次是操作操作之后的数组,还是操作原来的数组?
-
m很大,特别有可能会是负数,如果直接取余,可能会是负数下标,并且加上一次n,可能不会由负转正。
-
还有数据很大,可能会输出超时,考虑使用buffer进行输入输出。(额外注意点)
另外,一定要好好读题。理解题意才是做题的基础。这个题目,第二个注意点以及负数代表的含义刚开始就没有理解。导致错了两次。
考试中,估计就直接嗝屁了。因为没有数据。
import java.util.Scanner;
/**
* @author: Zekun Fu
* @date: 2022/10/20 23:21
* @Description: 移动,算法训练
*/
public class Main{
private static final int maxn = (int)1e6 + 5;
private static int[] a = new int[maxn];
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();
int k = sc.nextInt();
for (int i = 0; i < n; i++) {
a[i] = sc.nextInt();
}
int cur = 0;
for (int i = 0; i < m; i++) {
int x = sc.nextInt();
cur = (n + x + cur) % n;
while (cur < 0) cur = (cur + n) % n;
for (int j = 0; j < k; j++) {
if (j != k - 1)
System.out.print(a[(cur + j) % n] + " ");
else System.out.println(a[(cur + j) % n]);
}
}
}
}