0

Javaで次の問題を計算する方法を誰でも教えてくれます。有効な数字は 0 から 9 までの任意の数字で、# または * を除く 10 桁の長さで、チェスの駒が電話のキーパッドを移動中にトレースできる可能性のある有効な数字の数。ここでキングがいるとします。キングは実際のゲームと同じように、どの方向にも移動できますが、一度に 1 つのセルしか移動できません。

したがって、キーパッドは次のようになります。

         1  2  3
         4  5  6
         7  8  9
         *  0  #

そのため、ピースは毎回 10 回移動し、それによって作成されたそれぞれの固有の数字は有効な数字です。作品は最初の開始位置から旅を始めます。

更新: ピースは 1 つの場所に移動または滞在することができ (移動または滞在の両方が移動としてカウントされます)、セルを再訪することもできます (それぞれの移動権内で許可されている場合)。たとえば、キングが位置 1 から移動した場合、有効な数字を作成するための 3 つの有効な 10 回の移動パスは、1236547890 または 1111111111 または 1212121212 になります。

以下は、テスト用の 4 つのセルのみを含む 4 つのセルの正方形パッドの小さなバージョンのコードです。

public class King
{
private static final Integer[] ALLOWED_FROM_1 = {2, 3, 4};
private static final Integer[] ALLOWED_FROM_2 = {1, 3, 4};
private static final Integer[] ALLOWED_FROM_3 = {1, 2, 4};
private static final Integer[] ALLOWED_FROM_4 = {1, 2, 3};
List<Integer> visited;

public King()
{
    this.visited = new ArrayList<Integer>();

}

public List<Integer> get_destinations(int currentPos, int noOfMoves)
{
    if (noOfMoves == 0)
    {
        visited.add(currentPos);
        return visited;

    }
    else
    {

        List<Integer> possibleMoves = getPossibleMoves(currentPos);

        for (int i = 0; i < possibleMoves.size(); i++)
        {
            visited.add(possibleMoves.get(i));
            get_destinations(possibleMoves.get(i), noOfMoves - 1);

        }

        return visited;
    }



}


private List<Integer> getPossibleMoves(int currentPos)
{

    List<Integer> possibleMoves = new ArrayList<Integer>();

    switch (currentPos)
    {
        case 1 : possibleMoves.addAll(Arrays.asList(ALLOWED_FROM_1));
            break;

        case 2: possibleMoves.addAll(Arrays.asList(ALLOWED_FROM_2));
            break;

        case 3 : possibleMoves.addAll(Arrays.asList(ALLOWED_FROM_3));
            break;

        case 4 : possibleMoves.addAll(Arrays.asList(ALLOWED_FROM_4));
    }

    return possibleMoves;

}
}

上記のコードは、多くの異なる順列が欠落している部分的な回答のみを生成します。主な問題は、すべての順列を生成することをどのように正確に保証できるか、および上記のコードで正確にどの時点で (4 回の移動後に) 保存して後で取得する必要がある 4 桁の数字に到達するかです。また、 1234 1234 などの同じシーケンスの再訪を避けるにはどうすればよいので、基本的に最適化して、同じパスシーケンス/有効な番号が生成されないようにします。

すべての助けに感謝します。

4

3 に答える 3

0

ここに役立つかもしれないいくつかの疑似コードがあります。次のような方法で問題を再帰的に解決できます。

// Returns a list of all the destinations given a current location
// and the number of moves allowed (10 for King)
list<int> get_destinations(int cur_location, int num_moves) {
  // Base case. If no more moves are allowed, return current location as list.
  if(num_moves == 0) {
    return as_list(cur_location);
  } else {
    // List of all destinations possible from here
    list<int> destinations;
    // Get all the possible moves that are 1 step away.
    // For example: from 1, we would return 2 and 4
    list<int> possible_moves = get_possible_moves(cur_location);

    // For each of the moves generated from the last step,
    // recursively call get_destinations() with (num_moves - 1)
    for(int n:possible_moves) {
      destinations += get_destinations(n, num_moves - 1);
    }

    return destinations;
  }
}

次に、この関数を次のように呼び出します。

get_unique_nums(get_destinations); // Returns the set in the form you need it

宿題頑張ってください!

于 2012-04-26T14:54:18.477 に答える
0

非常に些細なアカデミックな再帰問題のようです。再帰が許可されている限り、言語は問題ではありません。

必要なもの:

  1. を設定します。F(n,m) 配列 (この場合は 3x4 の値) b. そして駒の初期位置。c. 任意の部分を許可するには、許可される動きを定義するデリゲート(関数ポインター、匿名クラス)関数を定義する必要があります

  2. 入力として受け取る次の適格な位置を識別するための、再帰的に呼び出し可能な関数を作成します。現在のピース位置(i、j)、b.最初の反復における再帰の深さ 1

  3. depth = 10 で再帰関数から戻る

  4. すべてのシーケンスも必要な場合は、この再帰関数を返せるようにします (非 void 型)。文字列が最適だと思います。

  5. コードを簡単にしたい場合は、許容されるセルのセット内のすべてのステップで *、# の存在を確認する必要はありません。最後の 10 シンボルの長い文字列が UNSIGNED LONG として解析可能であることを確認するだけです。再帰が長くなりすぎますが。
于 2012-04-26T15:11:13.233 に答える
0

王にとって、この繰り返しが来ています。2、1、2、1、3、4、3、1、2、3、4、2、3、4、3、1 _ _ _

特定の順序でセルを返すように getPossibleMove() 関数を作成できます。これにより、パスの繰り返しを回避できます。番号順に言うと、返されるはずです

2, 1, 2, 1,
2, 1, 2, 3,
2, 1, 2, 5,
2, 1, 4, 1,
2, 1, 4, 5,
2, 1, 4, 7

さらに、ピースを同じセルに移動させたくない場合は、getPossibleMove() 関数でそれらのセルのみを削除します。

どのようなコードを書くべきか分からなかったので、理論的な説明だけを書きました。

于 2012-04-27T06:34:38.127 に答える