(检查n个皇后问题)
在一个n´n的棋盘里如何放置互不攻击的n个皇后是个有名的问题。我们用坐标(i, j)来表示一个皇后被置于棋盘的第i行和第j列这一点上。一个在坐标(i, j)上的皇后和一个在坐标(u, v)上的皇后会互相攻击当且仅当 它们在同一行,或者同一列,或者同一对角线,也就是(i = u) 或 (j = v) 或 |i -u| = |j-v|。现在假设有n个皇后,他们的位置是 (a1, b1),(a2, b2),…,(an, bn)。请设计一个O(n)的算法来检查他们是否可以相安无事。
解:
将他们按行号排序后很容易检查是否有两个皇后在同一行。同样可以在O(n)时间内查出是否有在同一列的皇后。两个在坐标(i, j)和(u, v)上的皇后如果在对角线上互相攻击,那么必有|i -u| = |j-v|,也就是i - u = j - v,或者i - u = v – j。这也就是说必有 i - j = u – v,或者i + j = u + v。这两种情况同样可以用计数排序在O(n)时间内检查。下面是伪码。
Checking-N-Queen (A[1.. n], B[1..n]) //第k个皇后坐标为(A[k], B[k])
1 C[1.. n] ¬ A[1.. n]
2 Counting sort C[1.. n] 使 C[1] £ C[2] £ … £ C[n]
3 for k = 1 to (n-1)
4 if C[i] = C[i+1]
5 then return (Two queens are at the same row)
6 C[1.. n] ¬ B[1.. n]
7 Counting sort C[1.. n] 使 C[1] £ C[2] £ … £ C[n]
8 for k = 1 to (n-1)
9 if C[i] = C[i+1]
10 then return (Two queens are at the same column)
11 C[1.. n] ¬ (A[1.. n] - B[1.. n]) //So that C[k] = A[k] – B[k]
12 Counting sort C[1.. n] 使 C[1] £ C[2] £ … £ C[n]
13 for k = 1 to (n-1)
14 if C[i] = C[i+1]
15 then return (Two queens are at the same diagonal.)
16 C[1.. n] ¬ (A[1.. n] + B[1.. n]) //So that C[k] = A[k] + B[k]
17 Counting sort C[1.. n] 使 C[1] £ C[2] £ … £ C[n]
18 for k = 1 to (n-1)
19 if C[i] = C[i+1]
20 then return (Two queens are at the same diagonal.)
21 Return (These n queens will not attack each other.)
22 End