1008 陣列元素回圈右移問題

2020-08-14 01:04:39

題目

一個數組AA中存有N(>0)N(>0)個整數,在不允許使用另外陣列的前提下,將每個整數回圈向右移M(0)M(≥0)個位置,即將AA中的數據由(A0A1AN1)(A_{0}A_{1}···A_{N-1})變換爲(ANMAN1A0A1ANm1)(A_{N-M}···A_{N-1}A_{0}A_{1}···A_{N-m-1})(最後MM個數數回圈移至最前面的MM個位置)。如果考慮程式移動數據的次數儘可能少,要如何設計移動的方法?

輸入格式

每個輸入包含一個測試用例,第1行輸入N1N100N(1≤N≤100)M0M(≥0);第2行輸入NN個整數,之間用空格分隔。

輸出格式

在一行中輸出回圈右移MM位以後的整數序列,之間用空格分隔,序列結尾不能有多餘空格。

輸入樣例

6 2
1 2 3 4 5 6

輸出樣例

5 6 1 2 3 4

程式碼

#include <stdio.h>
#include <malloc.h>

void reserve(int *a, int m, int n){
    while(m < n){
        a[m]^=a[n]^=a[m]^=a[n];
        m++;
        n--;
    }
}

int main(void){
    int *a = NULL, n, m;
    scanf("%d %d",&n, &m);
    m = m%n;
    a = (int *) malloc(sizeof(int)*n);
    for(int i = 0; i < n; i++){
        scanf("%d",&a[i]);
    }
    reserve(a, n-m, n -1);
    reserve(a, 0, n-m-1);
    reserve(a, 0, n-1);
    for(int i = 0; i < n; i++){
        if(i == n-1){
            printf("%d",a[i]);
        }else{
            printf("%d ",a[i]);
        }
    }
    free(a);
    return 0;
}

小結

採用逆序3次的方法進行右移。首先將後MM個元素進行逆序,再將前面NMN-M個元素進行逆序,最後再將全部進行一次逆序即可。