找出两个女王在n * n棋盘上交叉(不会稳定)的方式?

时间:2017-01-12 11:02:31

标签: java c algorithm data-structures

我可以使用组合来做到这一点。 如果他们在同一个地方,皇后区不会稳定(受到攻击):

  1. 垂直
  2. 水平
  3. 对角线。
  4. 所以

    1. 可能的方式是:n * P(n,2)种方式
    2. 可能的方式是:n * P(n,2)种方式
    3. 可能的原因是:2 * ( P(n,2) + P(n-1,2) + ... + P(2,2)) + 2 * (P(n-1,2) + ... + P(2,2))
    4. 上述什么是合适的算法?

      class Main
      {
          public static void main (String[] args) throws java.lang.Exception
          {
              int n = 8;
              int arr[][] = new int[n][n];
              long x = 0;
              for (int i=0;i<n;i++){
                  for (int  j=0;j<n;j++){
      
                      x +=  Math.min(n-1-i, n-1-j) + Math.min(i, j) + Math.min(n-1-i,j) + Math.min(i,n-1-j);
      
                      x+= 2*n -2;
                  }
              }
      
              System.out.println(x);
           }
      }
      

      上述逻辑怎么样?

2 个答案:

答案 0 :(得分:2)

好吧,n * n董事会有

 All:      n * n * (n * n - 1) / 2
 Stable:   n * (n - 1) * (n - 2) * (3 * n - 1) / 6
 Unstable: n * (5 * n - 1) * (n - 1) / 3

位置。 (有关详细信息,请参阅https://oeis.org/A036464)。小n的一些示例:

 n   all   unstable   stable
-----------------------------  
 1     0 =        0  +     0
 2     6 =        6  +     0
 3    36 =       28  +     8
 4   120 =       76  +    44
 5   300 =      160  +   140
 6   630 =      290  +   340
 7  1176 =      476  +   700
 8  2016 =      728  +  1288
 9  3240 =     1056  +  2184
10  4950 =     1470  +  3480

实现(Java)很明显

private static long unstableCount(long n) {
  return n * (5 * n - 1) * (n - 1) / 3;
}

值得注意的是,

 All      = O(n**4)
 Stable   = O(n**4)
 Unstable = O(n**3) // just cube

因此,对于大型电路板,几乎所有位置都是稳定的。

如果皇后可辨别(例如你有红色皇后),你所要做的就是 multiply 2上面的数字和公式(交换皇后现在带来一个新的位置)。

private static long unstableDistinguishableCount(long n) {
  return n * (5 * n - 1) * (n - 1) / 3 * 2;
}

编辑:天真的采样实施(我们遍历所有可能的皇后位置)可能

private static long unstableCountNaive(int n) {
  long result = 0;

  for (int file1 = 0; file1 < n; ++file1)
    for (int rank1 = 0; rank1 < n; ++rank1)
      for (int file2 = file1; file2 < n; ++file2)
        for (int rank2 = file1 == file2 ? rank1 + 1 : 0; rank2 < n; ++rank2)
          if ((file1 == file2) ||                  // Same file 
              (rank1 == rank2) ||                  // Same rank
              (file1 + rank1 == file2 + rank2) ||  // Same top-left bottom-right diagonal
              (file1 - rank1 == file2 - rank2))    // Same bottom-left top-right diagonal
            result += 1;

  return result;
} 

编辑2 :如果我的想法正确,您可以计算对角线攻击然后使用对称性:

private static long unstableCountBetter(int n) {
  long result = 0;

  // Attacked by top-left bottom-right diagonal 
  for (int rank = 0; rank < n; ++rank)
    for (int file = 0; file < n; ++file)
      result +=
        (rank + file >= n ? 2 * n - 2 - (rank + file) : rank + file);

  result = 
    // symmetry: we have TWO diagonals
    result * 2 +       
    // At each postion (n * n of them) we have n - 1 checks on the same rank
    n * n * (n - 1) +
    // At each postion (n * n of them) we have n - 1 checks on the same file
    n * n * (n - 1);

  // /2 if queens are indistiguished (728 for 8x8 board)
  return result / 2;
} 

答案 1 :(得分:0)

问题有点不完整,但看着评论,我想我已经掌握了回答这个问题的所有信息。

由于你写道,有2种女王在3 * 3棋盘上交叉的方式有56种,你可以将两个女王视为不同,即。订购。例如。这两块板不同:

CREATE TABLE test_change (a int, b int, c int);

ALTER TABLE test_change CHANGE a a string b b doube c c decimal(11,2);

所以,你的问题的答案是n * n板的简单公式:

..q     ..Q
.Q.     .q.
...     ...