0

我需要打印出包含字母 A 到 F 的 N × N 网格,这样相邻的两个字母就不会相同。下面的代码打印出 N x N 网格,但是我只能让左右两侧的字母不同。我找不到让上面和下面的字母也不同的方法。我需要在不使用数组的情况下解决这个问题。字母必须是随机的。

public static void main(String[] args) {
    int N = StdIn.readInt();
    for (int column = 0; column < N; column++) {
        int x = 0;

        for (int row = 0; row < N; row++) {

            int c = (int) (Math.random() * 6 + 1);

            while (x == c) {
                c = (int) (Math.random() * 6 + 1);
            }
            if (c == 1) {
                System.out.print("A ");
            }
            if (c == 2) {
                System.out.print("B ");
            }
            if (c == 3) {
                System.out.print("C ");
            }
            if (c == 4) {
                System.out.print("D ");
            }
            if (c == 5) {
                System.out.print("E ");
            }
            if (c == 6) {
                System.out.print("F ");
            }

            x = c;

        }

        System.out.println();

    }
4

3 回答 3

0

2个队列很容易做到。

如果您分析以下内容,您应该意识到您实际上只需要一个大小为 N 的链表。

current是当前行,每个新元素都只是简单地排队。

last是上一行。current一旦你完成了一行,它的值就是我们要检查的第一个元素在前面。

我将第一行与其他行分开,以使事情更简单,更容易理解。

  int N = 10;
  Queue<Character> last,
                   current = new Queue<Character>();
  char prev = '0';
  for (int row = 0; row < N; row++)
  {
     char c;
     do { c = (char)(Math.random() * 6 + 'A'); }
     while (prev == c);
     current.enqueue(c);
     prev = c;
     System.out.print(c + " ");
  }
  System.out.println();
  for (int col = 1; col < N; col++)
  {
     last = current;
     current = new Queue<Character>();
     prev = '0';
     for (int row = 0; row < N; row++)
     {
        char c;
        do { c = (char)(Math.random() * 6 + 'A'); }
        while (last.peek() == c || prev == c);
        current.enqueue(c);
        last.dequeue();
        prev = c;
        System.out.print(c + " ");
     }
     System.out.println();
  }
于 2013-03-22T18:15:56.037 回答
0

您可以使用一对堆栈和一个候选字符来执行此操作。NxN 网格由最多包含 N 乘以 N 个字符的堆栈表示。用一副纸牌试试这个,用两个纸牌堆叠点代表堆叠,以了解它是如何工作的。

  1. 创建两个堆栈,A 和 B。为 A 中的项目数保留一个运行索引。
  2. 生成一个随机数。这是你的候选人。
  3. 如果堆栈 A 中有多个 N 项(您刚刚完成了一行),请跳到步骤 6。
  4. 弹出堆栈 A 的顶部并将其存储为 Check。
  5. 支票与候选人相邻吗?如果是,则将 Check 推回堆栈 A,然后返回步骤 2。(null 不相邻)
  6. 将 Check 推入堆栈 B。再弹出 N-2 个项目,将它们推入堆栈 B。
  7. 弹出堆栈 A 的顶部并将其存储为 Check。(堆栈 B 中应该有 N-1 项,Check 中应该有一个:一整行)
  8. 支票与候选人相邻吗?(null 不相邻)如果是,则将 Check 推回堆栈 A,从堆栈 B 中弹出每个项目,同时推入堆栈 A,然后返回步骤 2。
  9. 将支票推回堆栈 A。从堆栈 B 中弹出每个项目,同时将其推入堆栈 A。
  10. 将候选者压入堆栈 A。
  11. 增加索引。如果我们现在在堆栈 A 中有 NxN 项,我们就完成了:从堆栈 A 中弹出所有内容,然后将它们写在 NxN 网格中。否则返回步骤 2。

基本上,您正在抽一张牌,并检查最多两个项目。因为堆栈 A 保证永远不会有邻接关系,所以一旦放置了一个项目,就永远不必删除它。所以一旦你到达终点,你就完成了。

于 2013-03-22T19:18:26.113 回答
0

我帮你简化了你的 for 循环

for (int row = 0; row < N; row++) {
  char c = (char) (Math.random() * 6 + 'A');
  while (x == c) {
    c = (char) (Math.random() * 6 + 'A');
  }
  System.out.print(c + " ");
  x = c;
}

它使用字母的 ASCII 值,因此您不需要大的 if 语句。

您的问题不清楚允许哪些存储格式,但请考虑一下:如果您可以将每一行存储为一个字符串(一个在移动一行后被删除的临时字符串),您将如何检查该行中的一个字母是否在它下面重建与上面的字母匹配?将字符串视为数组(这是它的真实形式)。

于 2013-03-22T17:33:30.167 回答