C/C++

C++, ошибку в задаче понял но это меня опечалило)

#include <iostream>

using namespace std;

int main()
{
int n;
cin>>n;
int a[n];
for(int i=0;i<n;i++) {
cin>>a[i];
}
int k;
cin>>k;
int x;
for(int i=0;i<n;++i) {
if(i+k<n) a[i+k]=a[i];
else
if(i+k>=n) a[(i+k)%n]=a[i];
}
for(int i=0;i<n;++i) {
cout<<a[i]<<" ";
}
return 0;
}
Дана последовательность из N (1 ≤ N ≤ 100000) целых чисел и число K (|K| ≤ 100000). Сдвинуть всю последовательность (сдвиг - циклический) на |K| элементов вправо, если K – положительное и влево, если отрицательное.

В данной задаче нельзя использовать дополнительные массивы (списки). Обратите внимание, что нужно именно преобразовать имеющийся список и распечатать его целиком, а не создать новый, даже назвав его тем же самым именем (это возможно в языке Python).

Входные данные
В первой строке дано натуральное число N, во второй строке N целых чисел, а в последней целое число K. Все числа во входных данных не превышают 109.

Выходные данные
Требуется вывести полученную последовательность.

Примеры
входные данные
5
5 3 7 4 6
3
выходные данные
7 4 6 5 3
Мой код верный но он изменяет элементы массива слету и когда я хочу очередной раз сдвинуть элементы он берет не начальный массив(который не изменен) а берет уже измененный массив и путается. Поэтому можете слегка подсказать типа например как сохранить не измененный массив для дальнейшего действия (что то не поняли, я с легкойстью обьясню.)
Я вижу два простейших варианта циклического сдвига массива на K позиций:
  1. Сдвигать K раз на одну позицию.
  2. Делать сдвиг рекурсивно - каждый шаг рекурсии запоминает значение текущего элемента, вызывает рекурсию для следующего элемента, ставит запомненный элемент в нужное место.

Вариант сдвига по одной позиции:
 void rotate(int *arr, int n, int k) {
k %= n;
if (k < 0) { k += n; }
while (k--) {
int t = arr[n - 1];
for (int i = n - 1; i > 0; --i) {
arr[i] = arr[i - 1];
}
arr[0] = t;
}
}
Циклический сдвиг на k позиций влево эквивалентен циклическому сдвигу на n - k позиций вправо. Две первые строчки тела функции приводят k к диапазону 0..n-1.

Вариант рекурсии (вызываем rotate, которая подготавливает параметры для рекурсивной rot):
 void rot(int *arr, int n, int k, int i = 0) {
if (i >= n) { return; }
int t = arr[i];
rot(arr, n, k, i + 1);
arr[(i + k) % n] = t;
}

void rotate(int *arr, int n, int k) {
k %= n;
if (k < 0) { k += n; }
rot(arr, n, k);
}
В обоих вариантах приведение значения k к диапазону 0..n-1 можно вынести из rotate в main - тогда во втором варианте достаточно только ф-ции rot.
Лябошкин Юрий
Лябошкин Юрий
63 603
Лучший ответ
Аскар Какимов Благодарю