Jestem za tym żeby:
1. Unikać gołego new i delete, a zamiast nich używać std::vector
2. Unikać zbędnych alokacji, czyli alokować tablicę 2d w jednym kawałku, a nie każdy wiersz osobno.
3. Raz jeszcze unikać zbędnych alokacji, rotację można zrobić w miejscu bez tablicy pomocniczej. To pozwala również uniknąć kopiowania.
4. Definiować własne typy danych. Potrzebujesz tablicy dwuwymiarowej? - w twoim programie powinno się pojawić słowo class (może być struct, może być też #include, bo ktoś inny już zdefiniował typ którego potrzebujesz). C++ powstało po to by można było definiować własne typu danych, programowanie w C++ na tym głównie polega.
Przykład
#include <iostream>
#include <vector>
struct array2d
{
int height, width;
std::vector<int> data;
auto& operator () (int row, int col) { return data[row * width + col]; }
auto& operator () (int row, int col) const { return data[row * width + col]; }
friend std::ostream& operator << (std::ostream& out, const array2d& a)
{
for (int i = 0; i < a.height; ++i)
{
for (int j = 0; j < a.width; ++j)
out << a(i, j) << ' ';
out << '\n';
}
return out;
}
};
void rotate(array2d& a)
{
const auto t = a(0, 0);
for (int i = 0; i < a.width - 1; ++i)
a(0, i) = a(0, i + 1);
for (int i = 0; i < a.height - 1; ++i)
a(i, a.width - 1) = a(i + 1, a.width - 1);
for (int i = a.width - 1; i > 0; --i)
a(a.height - 1, i) = a(a.height - 1, i - 1);
for (int i = a.height - 1; i > 1; --i)
a(i, 0) = a(i - 1, 0);
a(1, 0) = t;
}
int main()
{
array2d a{3, 5, {1,2,3,4,5,6,7,8,9,0,1,2,3,4,5}};
std::cout << a << '\n';
rotate(a);
std::cout << a << '\n';
}
Jest to prosty przykład, dlatego dane w klasie array2d są publiczne, to ujdzie w prostym programie na SPOJa, w bardziej złożonych programach ścisła enkapsulacja ma fundamentalne znaczenie.
Przerobienie programu tak by dało się wczytywać tablicę ze standardowego wejścia pozostawiam jako ćwiczenie.
Ćwiczenie dla zaawansowanych - użyć std::rotate
Ćwiczenie dla zaawansowanych numer dwa - użyć std::experimental::ranges::rotate