Поэтому мой вклад должен быть nxn (n<= 20) матрица слов длиной не более 9 символов каждая. Вывод должен быть строковым предложением, сформированным путем чтения матрицы по часовой стрелке по спирали, начиная с верхнего левого угла. С некоторой помощью мне удалось заставить его работать … хотя у меня все еще есть некоторые проблемы с полным пониманием того, что именно происходит. Я абсолютно не знаю, как это сделать наоборот — против часовой стрелки, начиная с правого нижнего угла. Вот мой код до сих пор:
string s;
int hor = 0, vert = 0;
while (hor < n / 2 && vert < n / 2)
{
for (i = vert; i < n - vert; i++)
s = s + a[hor][i] + " ";
for (i = hor + 1; i < n - hor; i++)
s = s + a[i][n - vert - 1] + " ";
for (i = n - vert - 2; i >= vert; i--)
s = s + a[n - hor - 1][i] + " ";
for (i = n - hor - 2; i > hor; i--)
s = s + a[i][vert] + " ";
hor++;
vert++;
}
if (n % 2)
for (i = vert; i < n - vert; i++)
s = s + a[hor][i] + " ";
else
for (i = hor; i < n - hor; i++)
s = s + a[i][vert] + " ";
cout << s << endl;
Есть идеи? И нет ли более легкого способа сделать это?
Код вытекает непосредственно из этого алгоритма. (Обратите внимание, я не скомпилировал это, поэтому вам придется самостоятельно проверять наличие ошибок).
int x = n - 1; // Start at right.
int y = n - 1; // Start at bottom.
int spiral = 0; // Track the edges already visited (spiral).
int direction = 0; // 0=left, 1=up, 2=right, 3=down. You could also use an enum.
string s; // String builder.
for (int count = 0; count < 400; count++) { // One word per cell, 400 cells.
s = s + a[x][y] + " "; // Add the word.
if (direction == 0) { // Left
if (x > spiral) x--; // Check edge, advance if no edge.
else { y--; direction = 1; } // Change direction to up if edge is hit.
} else if (direction == 1) { // Up
if (y > spiral) y--; // Check edge, advance if no edge.
else { x++; direction = 2; } // Change direction to right if edge is hit.
} else if (direction == 2) { // Right
if (x < (n - 1) - spiral) x++; // Check edge, advance if no edge.
else { y++; direction = 3; spiral++; } // Change edge and direction to down.
} else if (direction == 3) { // Down
if (y < (n - 1) - spiral) y++; // Check edge, advance if no edge.
else { x--; direction = 0; } // Change direction to left if hit.
}
}
Свяжите каждую ячейку (x, y) с расстоянием и углом:
d(x,y) = max(abs(x - N/2), abs(y - N/2))
a(x,y) = atan2(y - N/2, x - N/2) + bias;
Затем отсортируйте данные сначала по расстоянию, затем по углу — порядок четко определен.
Объединенная метрика будет использовать, например, d(x,y) * 1000 + (int)a(x,y);
выполнить сортировку за один проход.
(Отказ от ответственности — это более или менее языковая независимость)