《PTA——C语言源代码》之第1008题

题目介绍

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

输入格式:每个输入包含一个测试用例,第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>
#define MAXSIZE 101

void move(int A[], int N, int M){
  for(; M < N - 1; ++M){
    A[N-M] = A[N-M-1];
  }
  A[1] = A[0];
}

int main(){
  int N, M, A[MAXSIZE]={0};  //A[0]用来存储需要移动的元素
  scanf("%d %d", &N, &M);
  for(int i = 1; i <= N; ++i){
    scanf("%d", &A[i]);
  }
  M = M % N;  //极其重要
  if(N == M){
    for(int i = N; i >= 1; --i){
    if( i == 1 )
      printf("%d", A[i]);
    else printf("%d ", A[i]);
     }
  }
  else {
    for(int i = 1; i <= M;++i){
      A[0] = A[N - i + 1];
      A[N - i + 1] = A[N - M];
      move(A, N, M);
    }
    for(int i = 1; i <= N; ++i){
      if( i == N )
        printf("%d", A[i]);
      else printf("%d ", A[i]);
    }
  }
  return 0;
}

知识分析

思路

拿到此题后的思路为,开辟一个数组大小为N+1,A[0]用来存储元素,下标1——N则为数组正常元素。要移动M个元素,先将最后一个值拿出来存储,然后数组其他的元素往后移动N-M个位置,最后将拿出来的元素放到A[0]即可。具体思路如下:
1. 最后一个元素A[N]赋值给A[0];
2. 令A[N - i + 1] = A[N - M];这样做的目的是将移动M个元素分解为移动1个元素。//晚点用好一点的术语描述,1≤i≤M;
3. 将A[1]到A[N-M]的值均往后移1位;移动完毕之后A[1] = A[0]
4. 重复上述3个步骤,直至i == M即可。

出错分析

  M = M % N;  //极其重要
  if(N == M){
    for(int i = N; i >= 1; --i){
        if( i == 1 )
        printf("%d", A[i]);
        else printf("%d ", A[i]);
      }
  }

提交完整的正确答案之前没有考虑极端情况,即
1. M>N的时候,此时应该对N求模。
2. M==N的时候,直接倒序输出即可。

猜你喜欢

转载自blog.csdn.net/manmandong123/article/details/81415507