Я вижу, что никто не использует только один for loop
и без рекурсии в коде, и поэтому я хочу внести свой вклад.
Идея такова:
Представьте себе, что в точке (0,0) находится черепаха, то есть левый верхний угол, обращенный к востоку (вправо)
Он будет продолжать движение вперед и каждый раз, когда он увидит знак , черепаха повернуть направо
Итак, если мы поместим черепаху в точку (0,0), обращенную вправо, и если мы поместим знаки в соответствующие места, черепаха будет проходить по спирали .
Теперь проблема заключается в следующем: «Куда поместить знаки?»
blockquote>Давайте посмотрим, где мы должны поместить знаки (отмеченные символом # и номерами на O) :
For a grid that looks like this: O O O O O O O O O O O O O O O O We put the signs like this: O O O # # O # O O # # O # O O # For a grid that looks like this: O O O O O O O O O O O O We put the signs like this: O O # # # O O # O # O # And for a grid that looks like this: O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O We put the signs like this: O O O O O O # # O O O O # O O # O O # O O O # O O O # O # O O O O O #Мы видим, что, если точка не находится в верхней левой части, знаки являются точками в точках, где расстояния до ближайшей горизонтальной границы и ближайшей вертикальной границы одинаковы, в то время как для верхней левой части расстояние до верхней границы больше, чем расстояние до левой границы, априори [7]
Это может быть реализовано простой функцией довольно легко, взяв минимум из-за того, что точка находится в верхнем правом углу, если точка горизонтально центрирована, а вверху слева. (
curRow
иheight-1-curRow
), то минимум (curCol
иwidth-1-curCol
) и сравните, если они одинаковы. Но нам нужно учитывать верхний левый случай, т. Е. Когда минимум равенcurRow
иcurCol
. В этом случае мы соответственно уменьшаем вертикальное расстояние.Вот код C:
#include <stdio.h> int shouldTurn(int row, int col, int height, int width){ int same = 1; if(row > height-1-row) row = height-1-row, same = 0; // Give precedence to top-left over bottom-left if(col >= width-1-col) col = width-1-col, same = 0; // Give precedence to top-right over top-left row -= same; // When the row and col doesn't change, this will reduce row by 1 if(row==col) return 1; return 0; } int directions[4][2] = {{0,1},{1,0},{0,-1},{-1,0}}; void printSpiral(int arr[4][4], int height, int width){ int directionIdx=0, i=0; int curRow=0, curCol=0; for(i=0; i<height*width; i++){ printf("%d ",arr[curRow][curCol]); if(shouldTurn(curRow, curCol, height, width)){ directionIdx = (directionIdx+1)%4; } curRow += directions[directionIdx][0]; curCol += directions[directionIdx][1]; } printf("\n"); } int main(){ int arr[4][4]= {{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}}; printSpiral(arr, 4, 4); printSpiral(arr, 3, 4); }
Какие выходы:
1 2 3 4 8 12 16 15 14 13 9 5 6 7 11 10 1 2 3 4 8 12 11 10 9 5 6 7