PAT 乙级 1008.数组元素循环右移问题 C++/Java
1008 数组元素循环右移问题 (20 分)
一个数组A中存有N(>)个整数,在不允许使用另外数组的前提下,将每个整数循环向右移M(≥)个位置,即将A中的数据由(A0A1⋯AN−1)变换为(AN−M⋯AN−1A0A1⋯AN−M−1)(最后M个数循环移至最前面的M个位置)。如果需要考虑程序移动数据的次数尽量少,要如何设计移动的方法?
输入格式:
每个输入包含一个测试用例,第1行输入N(1)和M(≥);第2行输入N个整数,之间用空格分隔。
输出格式:
在一行中输出循环右移M位以后的整数序列,之间用空格分隔,序列结尾不能有多余空格。
输入样例:
6 2
1 2 3 4 5 6
输出样例:
5 6 1 2 3 4
C++实现:
分析:
实现数组右移分3步:
(1)将数组颠倒(2)将数组 [ 0, m ) 颠倒(3)将数组 [ m, length) 颠倒
注意:
(1)右移位数 M 可能会比元素个数 N 大,要先进行 M % N 的操作
(2)判断 M 是否为 0
1 #include <iostream> 2 #include <vector> 3 #include <algorithm> 4 using namespace std; 5 6 int main() 7 { 8 //先将数组倒置,然后再将数组后的M位再倒置 9 int N, M; 10 cin >> N >> M; //元素个数,后移位数 11 vector<int> v(N); 12 for (int i = 0; i < N; ++i) 13 { 14 cin >> v[i]; 15 } 16 17 M %= N; //防止M比N大 18 if (M != 0) 19 { 20 reverse(v.begin(), v.begin() + N); //第一次将所有数组倒置 21 //由1-2-3-4-5-6变成6-5-4-3-2-1 22 23 reverse(v.begin(), v.begin() + M); //第二次将部分数组倒置 24 //由6-5-4-3-2-1变成5-6-4-3-2-1 25 26 reverse(v.begin() + M, v.end()); //第三次将部分数组倒置 27 //由6-5-4-3-2-1变成5-6-1-2-3-4 28 } 29 vector<int>::iterator it; 30 31 for (it = v.begin(); it != v.end() - 1; ++it) 32 { 33 cout << *it << " "; 34 35 } 36 cout << *it; 37 return 0; 38 }
Java实现:
1 import java.util.Scanner; 2 3 public class Main { 4 public static void main(String[] args) { 5 Scanner input = new Scanner(System.in); 6 int n = input.nextInt(); 7 int m = input.nextInt(); 8 int a[] = new int[n]; 9 int i = 0; 10 for (i = 0; i < n; i++) { 11 a[i] = input.nextInt(); 12 } 13 if (n < m) { 14 m = m % n; 15 } 16 if (n == m) { 17 for (i = 0; i < n; i++) { 18 if (i != 0) { 19 System.out.print(" "); 20 } 21 System.out.print(a[i]); 22 } 23 } else { 24 for (int j = n - m; j < n; j++) { 25 System.out.print(a[j] + " "); 26 } 27 for (int j = 0; j < n - m; j++) { 28 if (j != 0) { 29 System.out.print(" "); 30 } 31 System.out.print(a[j]); 32 } 33 } 34 } 35 }