每个输入包含一个测试用例,第1行输入N ( 1<=N<=100)、M(M>=0);第2行输入N个整数,之间用空格分隔。
在一行中输出循环右移M位以后的整数序列,之间用空格分隔,序列结尾不能有多余空格。
6 2 1 2 3 4 5 6
5 6 1 2 3 4
#include<stdio.h> //交换函数:用于交换from 和 end 所指向的值,这个函数的功能就是 //反转从from到end的这个数列 void Swap(int a[], int from, int end) { while(from<end){ a[from]^= a[end]^= a[from]^= a[end]; from++; end--; } } int main(void) { int M,N; scanf("%d",&N); scanf("%d",&M); int a[N]; int m= M%N; for(int i= 0; i< N; i++) scanf("%d",a+i); Swap(a,0,N-1);//先整体翻转过来使数列倒序 Swap(a,0,m-1);//然后部分翻转实现循环右移 Swap(a,m,N-1); for(int i= 0; i< N-1; i++) printf("%d ",a[i]); printf("%d",a[N-1]);//最后一个数字后不能有空格,害我找了好久的错误,就说么,哪儿出错了 }
思路:输入的时候就按照移序的方式输入。然后正常输出就可以了。牛逼吧! #include <iostream> using namespace std; int main() { int n, m; while (cin >> n >> m) { int * a = new int[n]; m = m % n; for (int i = 0,j = m; i < n; i++,j++) { if (j > n - 1) { j = 0; } cin >> a[j]; } for (int i = 0; i < n; i++) { if(i != n-1) cout << a[i] << " "; else { cout << a[i] << endl; } } } }
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int N = in.nextInt(), M = in.nextInt();
int count = 0;
int[] A = new int[N];
M = M % N;//M可能比N大
for (int i = 0; i < N; i++) {
A[i]=in.nextInt();
}
for(int i=N-M;i<N;i++)
{
System.out.print(A[i]);
count++;
if(count<N)
{
System.out.print(" ");
}
}
for(int i=0;i<N-M;i++)
{
System.out.print(A[i]);
count++;
if(count<N)
{
System.out.print(" ");
}
}
}
}
#include
#include
using namespace std;
int main(){
int a[110];
int n,m;
cin>>n>>m;
int count=0;
m=n%m;//确定移动位数
for(int i=0;in;i++){
cin>>a[i];
}
for(int i=n-m;in;i++){
couta[i];
count++;
if(countn)cout" ";
}
for(int i=0;in-m;i++){
couta[i];
count++;
if(countn)cout" ";
}
return 0;
}
import java.util.*; public class Main{ public static void main(String[] args){ Scanner sc=new Scanner(System.in); int n=sc.nextInt(); int m=sc.nextInt(); ArrayList<Integer> list=new ArrayList<Integer>(); ArrayList<Integer> result=new ArrayList<Integer>(); for(int i=0;i<n-m%n;i++){ list.add(sc.nextInt()); } for(int i=0;i<m%n;i++){ result.add(sc.nextInt()); } result.addAll(list); for(int i=0;i<result.size()-1;i++){ System.out.print(result.get(i)+" "); } System.out.print(result.get(result.size()-1)); } }
java版, 复杂度 O(N)。
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; // complexity O(N) public class Main { public static void main(String[] args) throws IOException { BufferedReader input = new BufferedReader(new InputStreamReader(System.in)); int N = 0, M = 0; int[] A = null; for (int i = 0; i < 2; i++) { if (i == 0) { String[] temp = input.readLine().split("\\s"); N = Integer.parseInt(temp[0]); M = Integer.parseInt(temp[1]); } else { String[] temp = input.readLine().split("\\s"); A = new int[N]; for (int j = 0; j < N; j++) { A[j] = Integer.parseInt(temp[j]); } } } input.close(); A = moveA(A, M); printer(A); } private static int[] moveA(int[] A, int M) { M %= A.length; if (M == 0) return A; reverse(A, 0, A.length - 1); reverse(A, 0, M - 1); reverse(A, M, A.length - 1); return A; } // reverse array from start to end private static void reverse(int[] a, int start, int end) { for (int i = start, j = end; i <= (start + end) / 2; i++, j--) { swap(a, i, j); } } private static void swap(int[] a, int left, int right) { int temp = a[left]; a[left] = a[right]; a[right] = temp; } private static void printer(int[] A) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < A.length; i++) { sb.append(A[i]); sb.append(" "); } sb.deleteCharAt(sb.length() - 1); System.out.println(sb.toString()); } }
import java.util.Scanner; class rightM{ public int[] aryN; public void inputMove(){ int n = 0; int step = 0; Scanner sc = new Scanner(System.in); n = sc.nextInt(); aryN = new int[n]; step = sc.nextInt(); for(int i=step%n;i<n;i++){ aryN[i] = sc.nextInt(); } for(int i=0;i<step%n;i++){ aryN[i] = sc.nextInt(); } for(int i=0;i<n;i++){ System.out.print(""+aryN[i]); if(i!=n-1) System.out.print(" "); } } } public class Main { public static void main(String[] args){ rightM rm = new rightM(); rm.inputMove(); } }
// 秒杀技巧:先取mod,然后在输入的时候就把位置移好! // (跳出惯性思维,一般人会觉得先把数据录好再移位) // 最后的输出也别具一格,哈哈~ // 希望可以采纳~ import java.util.Arrays; import java.util.Scanner; public class Main{ public static void main(String[] args) { Scanner in = new Scanner(System.in); while(in.hasNext()){ int n=in.nextInt(),m=in.nextInt(); m%=n; int[] arr=new int[n]; for (int i = 0,k=0; i < n; i++) { if(i+m<n){ arr[i+m]=in.nextInt(); } else{ arr[k++]=in.nextInt(); } } System.out.println(Arrays.toString(arr).replaceAll("\\[|\\]|,", "")); } } }
#include<bits/stdc++.h> using namespace std; const int Max=10010; int a[Max]; int main(){ int n,m; while(cin>>n>>m){ m=m%n; for(int i=0;i<n;i++){ cin>>a[i]; } for(int i=n-1;i>=0;--i){ a[m+i]=a[i]; } for(int i=m-1;i>=0;--i){ a[m-1-i]=a[n+m-1-i]; } for(int i=0;i<n;i++){ cout<<a[i]; if(i<n-1) cout<<" "; } cout<<endl; } return 0; }
#include <iostream> using namespace std; const int SIZE = 100; int main() { int N, M; cin >> N >> M; if (M >= N) M = M % N; int array[SIZE]; for (int i = 0; i < N; ++i) { cin >> array[i]; } for (int i = 0; i < M; ++i) { int tem = array[N - M + i]; for (int j = N - M + i; j > i; --j) { array[j] = array[j - 1]; } array[i] = tem; } cout << array[0]; for (int i = 1; i < N; ++i) { cout << " " << array[i]; } cout << endl; return 0; }
//直接按结果输入hh #include<iostream> using namespace std; int arr[110]; int main(){ int n, k; while(cin>>n>>k){ for(int i=k%n; i<n; i++){ cin>>arr[i]; } for(int i=0; i<k%n; i++){ cin>>arr[i]; } for(int i=0; i<n; i++){ if(i==n-1){ cout << arr[i] << endl; } else { cout << arr[i] << " "; } } } return 0; }
#include <stdio.h> (737)#include <algorithm> //reverse() 左闭右开 using namespace std; int main() { int n,m; scanf("%d %d",&n,&m); m%=n; //m可能大于n int a[n]; for(int i=0;i<n;i++) scanf("%d",&a[i]); reverse(a,a+n); reverse(a,a+m); reverse(a+m,a+n); //左闭右开 for(int i=0;i<n;i++) { printf("%d",a[i]); if(i!=n-1) printf(" "); } return 0; }
这道题最常规的解法是手动去移动,但这显然体现不出算法的伟大。下面介绍两种较为高效的方法:
所谓翻转法,就是分别将[0, n - 1]、[0, m - 1]、[m, n - 1]翻转。 比如对于n = 7,m = 2,[1 2 3 4 5 6] 先翻转区间[0, n - 1],得到[6 5 4 3 2 1] 再翻转区间[0, m - 1],得到[5 6 4 3 2 1] 最后翻转区间[m, n - 1],得到[5 6 1 2 3 4] 三次翻转得到的最终结果就是向右循环移动两次的结果。
稍微知道一点数据结构的都知道队列这种数据结构,先进先出的特性。只要把队头的元素出队、再入队(队尾),重复n - m次。 比如对于n = 7,m = 2,队列[1 2 3 4 5 6] 队头放入队尾 [2 3 4 5 6 1] 队头放入队尾 [3 4 5 6 1 2] 队头放入队尾 [4 5 6 1 2 3] 队头放入队尾 [5 6 1 2 3 4] 4次出队、入队操作得到的最终结果就是向右循环移动两次的结果。 如果你还知道有一种双端队列(队头、队尾都可以进行出队、入队操作)的数据结构, 其实对于这种情况只需要2次把队尾放入队头就行。 当然你也可以手动构造一个链表,将链表的头部放入链表的尾部
循环移动移动n次与不移动的是一样的,所以当m >
n时可以缩减移动次数m %= n
。
移动规律——翻转法
#include <iostream> (720)#include <cstring> using namespace std; int main() { int n = 0, m = 0, tempNum, numbers[101] = {0}; //primerTable[i]记录i是否是素数 while (scanf("%d %d", &n, &m) != EOF) { m %= n;//移动n次与不移动是一样的 //获取输入的数组 for (int i = 0; i < n; ++i) { scanf("%d", numbers + i); } //将[0, n - 1]区间翻转 for (int left = 0, right = n - 1; left < right; ++left, --right) { tempNum = numbers[left]; numbers[left] = numbers[right]; numbers[right] = tempNum; } //将[0, m - 1]区间翻转 for (int left = 0, right = m - 1; left < right; ++left, --right) { tempNum = numbers[left]; numbers[left] = numbers[right]; numbers[right] = tempNum; } //将[m, n - 1]区间翻转 for (int left = m, right = n - 1; left < right; ++left, --right) { tempNum = numbers[left]; numbers[left] = numbers[right]; numbers[right] = tempNum; } for (int i = 0; i < n - 1; ++i) { printf("%d ", numbers[i]); } printf("%d\n", numbers[n - 1]); } return 0; } ———————————————— 版权声明:本文为CSDN博主「hestyle」的原创文章,遵循 CC 4.0 BY 版权协议,转载请附上原文出处链接及本声明。 原文链接:https://hestyle.blog.csdn.net/article/details/104761085
数据结构——队列(链表)
#include <iostream> (720)#include <queue> using namespace std; int main() { int n = 0, m = 0, tempNum; //primerTable[i]记录i是否是素数 while (scanf("%d %d", &n, &m) != EOF) { queue<int> myQue;//辅助队列,注意这是平常的单端队列,只能从队头出队,队尾入队,并不是双端队列deque for (int i = 0; i < n; ++i) { scanf("%d", &tempNum); myQue.push(tempNum); } //循环右移n次与不移动的效果是一样的 m %= n; //连续操作n - m次,将队头放入队尾 for (int i = n - m; i > 0; --i) { //将队头放入队尾 myQue.push(myQue.front()); myQue.pop(); } //输出结果 for (int i = n - 1; i > 0; --i) { printf("%d ", myQue.front()); myQue.pop(); } printf("%d\n", myQue.front()); myQue.pop(); } return 0; } ———————————————— 版权声明:本文为CSDN博主「hestyle」的原创文章,遵循 CC 4.0 BY 版权协议,转载请附上原文出处链接及本声明。 原文链接:https://hestyle.blog.csdn.net/article/details/104761085
//三次翻转 #include <stdio.h> #include <stdlib.h> void reverse(int*, int, int); int main() { int m, n; while(~scanf("%d %d", &n, &m)) { m = m % n; int s[100] = {0}; int i; for(i = 0; i < n; i++) scanf("%d", s + i); reverse(s, 0, n - m - 1); reverse(s, n - m, n - 1); reverse(s, 0, n - 1); for(i = 0; i < n; i++) { if(i == 0) printf("%d", s[i]); else printf(" %d", s[i]); } printf("\n"); } return 0; } void reverse(int s[], int start, int end) { for(int i = 0; i < (end - start + 1) / 2; i++) { int temp = s[start + i]; s[start + i] = s[end - i]; s[end - i] = temp; } }
#include<bits/stdc++.h> using namespace std; void reverse(int a[],int start,int end){ for(int i=start;i<=(end+start)/2;i++){ int temp=a[i]; a[i]=a[end-i+start]; a[end-i+start]=temp; } } int main(){ int len,move; while(~scanf("%d %d",&len,&move)){ int a[105]; for(int i=0;i<len;i++)scanf("%d",&a[i]); move%=len; reverse(a,0,len-(move+1)); reverse(a,len-move,len-1); reverse(a,0,len-1); for(int i=0;i<len-1;i++)printf("%d ",a[i]); printf("%d",a[len-1]); printf("\n"); } return 0; }