我是靠谱客的博主 执着铃铛,这篇文章主要介绍PAT乙级C语言1008 数组元素循环右移问题,现在分享给大家,希望可以做个参考。

1008 数组元素循环右移问题

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

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

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

输入样例:

复制代码
1
2
3
6 2 1 2 3 4 5 6

输出样例:

复制代码
1
2
5 6 1 2 3 4
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include<stdio.h> int main() { int n;//输入n个数 int m;//输入数向右移 int a[100]; scanf("%d%d",&n,&m); for(int i = 0 ; i < n;i++) { scanf("%d",&a[i]); } if(1 == n) { printf("%d",a[0]); } else if(n > m ) { for(int i = n - m ; i < n;i++) { if (i == n - m) printf("%d",a[i]); else printf(" %d",a[i]); } for(int i = 0; i < n - m;i++) printf(" %d",a[i]); } else if(m % n == 0) { for(int i = 0;i < n;i++) { if (i == 0) printf("%d",a[i]); else printf(" %d",a[i]); } } else { for(int i = n - m % n ; i < n;i++) { if (i == n - m % n) printf("%d",a[i]); else printf(" %d",a[i]); } for(int i = 0; i < n - m % n;i++) printf(" %d",a[i]); } return 0; }

没考虑到一些特殊情况,按着牛客网的测试案例来改的,所以写的繁琐。但是牛客网的有个测试点没过去,pat的能过去,就没继续深究了。

其中取余的想法是从https://blog.csdn.net/qq_40840749/article/details/81781789 以及https://blog.csdn.net/qq_15046309/article/details/86516764 两位博主中的代码看到的。
1)不要想当然地认为N>M,所以在M>N时需要对M进行处理,即作取余计算M=M%N
2)考察的是输出格式的问题,注意一点,即移动的数值会大于原来数组的长度。因此实际的移动数是对数组的长度取余

以及这个博主的想法也可以借鉴,还没有仔细深究。
https://www.cnblogs.com/tenjl-exv/p/9783143.html
思路分析:
  对于循环移动的问题
  将移动个数所在位置左右两边分别反序,再整体反序即可
  PS:
    针对M大于N的情况,取mod(n,m)
    如果向右移动,则从右向左数M
    如果向左移动,则从左向右数M

2022-10-02更新
时隔多年又重新做了这道题。本来想着使用int a[N],输入的时候使用while(N–),结果在尝试输出数组的时候输出为空。再输出N值的时候发现输出为-1。看了眼书中的前半部分,就把数组定义为int a[110]了。这回的思路是,先校正M的值,在输入的时候就输入到它移动后的位置上,最后直接正常输出了。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include<stdio.h> int main(){ int M, N; scanf("%d%d", &N, &M); int a[110]; int n = M % N; for(int i = n; i < N; i++){ scanf("%d", &a[i]); } for(int i = 0; i < n; i++){ scanf("%d", &a[i]); } for(int j = 0; j < N; j++){ if(j != N-1){ printf("%d ", a[j]); }else{ printf("%d", a[j]); } } return 0; }

书中思路:
题目中虽然给出了很多限制,例如不允许使用另外的数组、又要考虑移动数据的次数最少,但实际上却只测试循环右移之后得到的结果而不管过程。

首先需要注意题目并没有给定M的最大值,因此不能直接认为M< N,而需要在读入N和M后令M=M%N,这样就可以保证M<N,使后面操作更简单。这样做的依据是:对一个长度为N的序列,右移N位之后的序列和当前序列是相同的。

在得到新的M后,可以直接输出序列从N-M号元素到N-1号元素,再输出0号元素到N-M-1号元素即可。

最后

以上就是执着铃铛最近收集整理的关于PAT乙级C语言1008 数组元素循环右移问题的全部内容,更多相关PAT乙级C语言1008内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(77)

评论列表共有 0 条评论

立即
投稿
返回
顶部