B1008. 数组元素循环右移问题 (20)

来源:互联网 发布:java给pom.xml赋值取值 编辑:程序博客网 时间:2024/06/07 02:03

1008. 数组元素循环右移问题 (20)

时间限制
400 ms
内存限制
65536 kB
代码长度限制
8000 B
判题程序
Standard

一个数组A中存有N(N>0)个整数,在不允许使用另外数组的前提下,将每个整数循环向右移M(M>=0)个位置,即将A中的数据由(A0 A1……AN-1)变换为(AN-M …… AN-1 A0 A1……AN-M-1)(最后M个数循环移至最前面的M个位置)。如果需要考虑程序移动数据的次数尽量少,要如何设计移动的方法?

输入格式:每个输入包含一个测试用例,第1行输入N ( 1<=N<=100)、M(M>=0);第2行输入N个整数,之间用空格分隔。

输出格式:在一行中输出循环右移M位以后的整数序列,之间用空格分隔,序列结尾不能有多余空格。

输入样例:
6 21 2 3 4 5 6
输出样例:
5 6 1 2 3 4
这个题之前类似见过,早些年408真题就有类似的,总的方法有三个 ,一个是用数组转置,第二个是晴神给的方法,移动最少,第三个是取巧了,直接从原始输出循环右移后的结果,也是晴神给的思路,结果见下。
    //转置数组法 #include<cstdio>void invert(int A[], int start, int end){int temp;if(start < 1 || end > 100 ) return;while(start < end){temp = A[start];A[start] = A[end];A[end] = temp;++start;--end;}} int main(){int n, m;scanf("%d %d", &n, &m);m = m % n; int A[110];for(int i = 1; i <= n; ++i){scanf("%d", &A[i]);}invert(A, 1, n-m);invert(A, n-m+1, n);invert(A, 1, n);for(int i = 1; i <= n; ++i){if(i == n){ printf("%d", A[i]);break; }printf("%d ", A[i]); }return 0;}
//    这个方法是晴神给的思路 ,移动次数最少
#include<cstdio>const int maxn = 110;int gcd(int a, int b){return (b == 0) ? a : gcd(b, a % b);/*if(b == 0)return a;else return gcd(b, a % b);*/}int main(){int n, m, a[maxn];scanf("%d %d", &n, &m);for(int i = 0; i < n; ++i)scanf("%d", &a[i]);m = m % n;if(m != 0){int d = gcd(m , n);int pos, next, temp;for(int i = n - m; i < n - m + d; ++i){temp = a[i];pos = i;do{next = (pos - m + n) % n;if(next != i)  a[pos] = a[next];else a[pos] = temp; pos = next;}while(pos != i);}}for(int i = 0; i < n; ++i)printf("%s%d", i ? " " : "", a[i]);/*for(int i = 0; i < n; ++i){printf("%d", a[i]);if(i < n - 1) printf(" ");}*/return 0;} 


      //直接输出法 #include<cstdio>int main(){int n, m, count = 0;int A[110];scanf("%d %d", &n, &m);m = m % n;for(int i = 0; i < n; ++i)scanf("%d", &A[i]);for(int i = n-m; i < n; ++i){printf("%d", A[i]);++count;if(count < n)printf(" ");}for(int i = 0; i < n-m; ++i){printf("%d", A[i]);++count;if(count < n)printf(" ");}}


0 0
原创粉丝点击