Top.Mail.Ru
Ответы

Как вывести матрицу по спирали? С++

Есть задача - вывести матрицу размерами n х m, заполненную числами от 1 до n*m по спирали.
Я попробовал это сделать поэтапно - сначала верхняя строка слева направо, потом крайний правый столбец сверху вниз. Потом наоборот - нижняя строка справа налево и крайний левый столбец снизу вверх. И потом идет смещение на одну клетку по диагонали, а до этого еще я уменьшаю n и m чтобы матрица не перезаписывала элементы.
Но что-то с моим кодом не так. Если что, я знаю только азы: циклы, условный оператор, вектора, числа ну у вот двумерные массивы изучаю.

1234567891011121314151617181920212223242526272829303132333435363738394041424344
 #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;}}

Аватар пользователя
Высший разум

Нам нужно менять направление в двух случаях: следующая клетка находится за границами массива или следующая клетка уже заполнена. Обнулим массив - чтобы отличать пустые и заполненные клетки, а смещения сделаем отдельным массивом - чтобы не делать отдельные циклы по направлениям.

1234567891011121314151617181920
 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;
}