给定一个整数N,这样就存在一个大小为N * N的棋盘和一个由K对整数组成的数组pos [] [] ,它们表示在给定棋盘中放置的位置。任务是找到可以放置在给定棋盘上的最大数量的车子,以使任何车子都不会攻击其他车子。按字典顺序打印位置。
例子:
Input: N = 4, K = 2, pos[][] = {{1, 4}, {2, 2}}
Output:
2
3 1
4 3
Explanation:
Only 2 more rooks can be placed on the given chessboard and their positions are (3, 1) and (4, 3).
Input: N = 5, K = 0, pos[][] = {}
Output:
5
1 1
2 2
3 3
4 4
5 5
Explanation:
Since the chessboard is empty we can place 5 rooks the given chessboard and their positions are (1, 1), (2, 2), (3, 3), (4, 4) and (5, 5).
天真的方法:最简单的方法是尝试将棋盘放置在棋盘的每个空白位置,并检查棋盘是否攻击了已经放置的棋盘。步骤如下:
- 初始化大小为N * N的2D矩阵M [] []来表示棋盘,并将已经给定的车子放置在棋盘中。
- 横切完整的矩阵M [] []并检查第i行和第j列是否包含任意行
- 如果第ith行和第j列均不包含任何规则,则将规则放置在此处,并将此单元格添加到结果中。
- 否则,移动到棋盘上的下一个空白单元格。
时间复杂度: O(N 3 )
辅助空间: O(N 2 )
高效方法:该方法基于以下想法:根据鸽孔原理,最多可以将(N – K)个白嘴放在棋盘上。步骤如下:
- 由于给定的白名单中没有两个是相互攻击的,因此输入中给定的所有行都必须是唯一的。同样,输入中给定的所有列都必须是唯一的。
- 因此,仅将Rook放置在N-K个未使用的行和N-K个未使用的列中。
- 因此,通过将最小的未使用的行与最小的未使用的列配对,第二最小的未使用的行与第二最小的未使用的列配对,可以实现字典上的最小配置。
下面是上述方法的实现:
C++
// C++ Program to implement
// the above approach
#include
using namespace std;
// Function to print the maximum rooks
// and their positions
void countRooks(int n, int k,
int pos[2][2])
{
int row[n] = {0};
int col[n] = {0};
// Initialize row and col array
for (int i = 0; i < n; i++)
{
row[i] = 0;
col[i] = 0;
}
// Marking the location of
// already placed rooks
for (int i = 0; i < k; i++)
{
row[pos[i][0] - 1] = 1;
col[pos[i][1] - 1] = 1;
}
int res = n - k;
// Print number of non-attacking
// rooks that can be placed
cout << res << " " << endl;
// To store the placed rook
// location
int ri = 0, ci = 0;
while (res-- > 0)
{
// Print lexographically
// smallest order
while (row[ri] == 1)
{
ri++;
}
while (col[ci] == 1)
{
ci++;
}
cout << (ri + 1) << " " <<
(ci + 1) << " " <
Java
// Java program for the above approach
public class GFG {
// Function to print the maximum rooks
// and their positions
private static void countRooks(int n, int k,
int pos[][])
{
int row[] = new int[n];
int col[] = new int[n];
// Initialize row and col array
for (int i = 0; i < n; i++) {
row[i] = 0;
col[i] = 0;
}
// Marking the location of
// already placed rooks
for (int i = 0; i < k; i++) {
row[pos[i][0] - 1] = 1;
col[pos[i][1] - 1] = 1;
}
int res = n - k;
// Print number of non-attacking
// rooks that can be placed
System.out.println(res + " ");
// To store the placed rook
// location
int ri = 0, ci = 0;
while (res-- > 0) {
// Print lexographically
// smallest order
while (row[ri] == 1) {
ri++;
}
while (col[ci] == 1) {
ci++;
}
System.out.println(
(ri + 1)
+ " " + (ci + 1)
+ " ");
ri++;
ci++;
}
}
// Driver Code
public static void main(String[] args)
{
// Size of board
int N = 4;
// Number of rooks already placed
int K = 2;
// Position of rooks
int pos[][] = { { 1, 4 }, { 2, 2 } };
// Function call
countRooks(N, K, pos);
}
}
Python3
# Python3 program for the above approach
# Function to prthe maximum rooks
# and their positions
def countRooks(n, k, pos):
row = [0 for i in range(n)]
col = [0 for i in range(n)]
# Marking the location of
# already placed rooks
for i in range(k):
row[pos[i][0] - 1] = 1
col[pos[i][1] - 1] = 1
res = n - k
# Print number of non-attacking
# rooks that can be placed
print(res)
# To store the placed rook
# location
ri = 0
ci = 0
while (res > 0):
# Print lexographically
# smallest order
while (row[ri] == 1):
ri += 1
while (col[ci] == 1):
ci += 1
print((ri + 1), (ci + 1))
ri += 1
ci += 1
res -= 1
# Driver Code
if __name__ == '__main__':
# Size of board
N = 4
# Number of rooks already placed
K = 2
# Position of rooks
pos= [ [ 1, 4 ], [ 2, 2 ] ]
# Function call
countRooks(N, K, pos)
# This code is contributed by mohit kumar 29
C#
// C# program for the above approach
using System;
class GFG{
// Function to print the maximum rooks
// and their positions
private static void countRooks(int n, int k,
int [, ]pos)
{
int []row = new int[n];
int []col = new int[n];
// Initialize row and col array
for (int i = 0; i < n; i++)
{
row[i] = 0;
col[i] = 0;
}
// Marking the location of
// already placed rooks
for (int i = 0; i < k; i++)
{
row[pos[i, 0] - 1] = 1;
col[pos[i, 1] - 1] = 1;
}
int res = n - k;
// Print number of non-attacking
// rooks that can be placed
Console.WriteLine(res + " ");
// To store the placed rook
// location
int ri = 0, ci = 0;
while (res -- > 0)
{
// Print lexographically
// smallest order
while (row[ri] == 1)
{
ri++;
}
while (col[ci] == 1)
{
ci++;
}
Console.WriteLine((ri + 1) + " " +
(ci + 1) + " ");
ri++;
ci++;
}
}
// Driver Code
public static void Main(String[] args)
{
// Size of board
int N = 4;
// Number of rooks already placed
int K = 2;
// Position of rooks
int [, ]pos = {{1, 4}, {2, 2}};
// Function call
countRooks(N, K, pos);
}
}
// This code is contributed by Rajput-Ji
2
3 1
4 3
时间复杂度: O(N 2 )
辅助空间: O(N 2 )