Как вывести матрицу по спирали? С++
Есть задача - вывести матрицу размерами n х m, заполненную числами от 1 до n*m по спирали.
Я попробовал это сделать поэтапно - сначала верхняя строка слева направо, потом крайний правый столбец сверху вниз. Потом наоборот - нижняя строка справа налево и крайний левый столбец снизу вверх. И потом идет смещение на одну клетку по диагонали, а до этого еще я уменьшаю n и m чтобы матрица не перезаписывала элементы.
Но что-то с моим кодом не так. Если что, я знаю только азы: циклы, условный оператор, вектора, числа ну у вот двумерные массивы изучаю.
#include <iostream>
#include <iomanip>
#include <cmath>
#include <vector>
using namespace std;
int main() {
int n, m, cnt = 1, i, j, x = 0, y = 0, f = 1;
static int a[100][100];
cin >> n >> m;
while (cnt != (m * n)) {
i = x;
j = y;
for (j = x; j < m; j++) { //строка слева направо
a[i][j] = cnt;
cnt++;
}
if (j == (m - 1)) { m = m - 1; }
for (i = y; i < n; i++) { //столбец сверху вниз
a[i][j] = cnt;
cnt++;
}
if (i == (n - 1)) { n = n - 1; }
for (j = m; j > x; j--) { //строка справа налево
a[i][j] = cnt;
cnt++;
}
for (i = n; i < y; i--) { //столбец снизу вверх
a[i][j] = cnt;
cnt++;
}
x++;
y++;
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cout << setw(4) << a[i][j];
}
cout << endl;
}
}
#include <iostream>
#include <iomanip>
void sf(int **a, int m,int n){
int val=1, k=0, l=0;
while(k<m && l<n){
for(int i=l;i<n;++i)a[k][i]=val++; k++;
for(int i=k;i<m;++i)a[i][n-1]=val++; n--;
if(k<m){for(int i=n-1;i>=l;--i)a[m-1][i]=val++; m--;}
if(l<n){for(int i=m-1;i>=k;--i)a[i][l]=val++; l++;}}}
using namespace std;
int main(){
int m,n; cout<<"N M: "; cin>>m>>n;
int **a=new int*[m]; for(int i=0;i<m;++i)a[i]=new int[n];
sf(a,m,n); for(int i=0;i<m;i++){
for(int j=0;j<n;j++)cout<<setw(4)<<a[i][j]; cout<<endl;}}
Нам нужно менять направление в двух случаях: следующая клетка находится за границами массива или следующая клетка уже заполнена. Обнулим массив - чтобы отличать пустые и заполненные клетки, а смещения сделаем отдельным массивом - чтобы не делать отдельные циклы по направлениям.
int n, m, x = -1, y = 0, k = 0, cnt = 0;
static int a[100][100] = {0}; // обнуляем массив при создании
int d[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; // Таблица смещений
cin >> n >> m;
while (cnt < n * m) {
int y1 = y + d[k][0], x1 = x + d[k][1]; // следующая клетка
if (y1 < 0 || y1 >= n || x1 < 0 || x1 >= m || a[y1][x1]) {
k = (k + 1) % 4; // меняем направление
} else {
a[y = y1][x = x1] = ++cnt; // заполняем клетку
}
}
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
cout << setw(4) << a[i][j];
}
cout << endl;
}
#include <iostream>
#include <vector>
using namespace std;
void spiralOrder(vector<vector<int>>& matrix) {
int row = matrix.size();
int col = matrix[0].size();
int top = 0, bottom = row - 1, left = 0, right = col - 1;
int dir = 0;
while (top <= bottom && left <= right) {
if (dir == 0) {
for (int i = left; i <= right; i++) {
cout << matrix[top][i] << " ";
}
top++;
}
else if (dir == 1) {
for (int i = top; i <= bottom; i++) {
cout << matrix[i][right] << " ";
}
right--;
}
else if (dir == 2) {
for (int i = right; i >= left; i--) {
cout << matrix[bottom][i] << " ";
}
bottom--;
}
else if (dir == 3) {
for (int i = bottom; i >= top; i--) {
cout << matrix[i][left] << " ";
}
left++;
}
dir = (dir + 1) % 4;
}
}
int main() {
vector<vector<int>> matrix = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
spiralOrder(matrix);
return 0;
}