1

したがって、私の入力は、それぞれ 9 文字を超えない単語の nxn (n<=20) 行列である必要があります。出力は、行列を左上隅から時計回りに螺旋状に読み取ることによって形成された文字列の文である必要があります。いくつかの助けを借りて、私はそれを機能させることができました..正確に何が起こっているのかを完全に理解するのにまだ苦労しています. 私はそれを逆に行う方法がまったくわかりません-右下隅から始まる反時計回りのスパイラル。これまでの私のコードは次のとおりです。

    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;

何か案は?そして、これを行う簡単な方法はありませんか?

4

2 に答える 2

2
  1. 変数 x と y を位置に使用すると、追跡が容易になります。
  2. 状態変数を使用して方向を追跡します。反時計回りは、左、上、右、そして下です。
  3. 各位置から単語を追加します。
  4. エッジに当たるまで位置を進めてから、方向を変えます。これを 4 回 (各方向に 1 回) 実行し、らせんの幅を表すエッジ カウンターをインクリメントします。
  5. これを 400 回 (20*20) 回実行したら完了です。

コードはそのアルゴリズムから直接流れます。(注、これはコンパイルしていないので、自分でエラーを確認する必要があります)。

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.
  }
}
于 2014-01-23T20:15:14.550 に答える
1

すべてのセル (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);、1 回のパスで並べ替えを実行するために使用します。

(免責事項 -- これは多かれ少なかれ言語に依存しません)

于 2014-01-23T20:22:47.973 に答える