给定一组棋子的坐标,判断是否可以互相攻击。如果两个棋子的横纵坐标任意一个相同,则认为它们可以互相攻击。(提示:使用哈希表)
简介:给定一组棋子的坐标,判断是否可以互相攻击。如果两个棋子的横纵坐标任意一个相同,则认为它们可以互相攻击。(提示:使用哈希表)
算法思路
算法思路:
- 首先我们需要读取所有的棋子坐标,并将其存储在一个哈希表中。其中,哈希表的 key 是坐标(用字符串表示),value 则是该坐标上是否存在棋子。
- 如果两个棋子横纵坐标任意一个相同,则认为它们可以互相攻击。因此,我们只需要遍历所有的棋子坐标,比较每一对棋子的坐标是否满足攻击条件即可。
下面是C++代码实现,每行注释详细解释其作用:
#include <iostream> #include <unordered_map> using namespace std; bool canAttack(int x1, int y1, int x2, int y2) { // 判断两个棋子是否能够攻击 return x1 == x2 || y1 == y2; // 横纵坐标任意一个相同即为攻击范围 } bool allQueensSafe(int n, int* rows, int* cols) { // 实现函数allQueensSafe,判断N皇后问题中的棋子是否互相攻击 unordered_map<string, bool> board; // 创建一个哈希表,用来储存棋盘中已经存在的棋子 for (int i = 0; i < n; i++) { // 遍历所有棋子 int row1 = i, col1 = cols[i]; board[to_string(row1) + "," + to_string(col1)] = true; // 将每个棋子的坐标存储到哈希表中 for (int j = i + 1; j < n; j++) { // 比较两个棋子的坐标是否可以互相攻击 int row2 = j, col2 = cols[j]; if (canAttack(row1, col1, row2, col2)) { // 如果两个棋子可以互相攻击,则N皇后问题不合法,返回false return false; } } } return true; // 如果所有棋子都不存在攻击范围,则说明N皇后问题合法,返回true } int main() { int rows[] = {0, 3, 1, 4, 2}; // 棋子坐标,其中rows[i]表示第i个棋子所在的行(从0开始),cols[i]表示它所在的列 int cols[] = {0, 2, 4, 1, 3}; int n = sizeof(rows) / sizeof(rows[0]); // 计算棋子数量 bool ans = allQueensSafe(n, rows, cols); // 判断N皇后问题是否合法 if (ans) cout << "All queens are safe" << endl; else cout << "Queens can attack each other" << endl; return 0; }
需要注意的是,在上述代码实现中,我们基于哈希表来判断是否存在攻击关系。具体而言,将每个棋子的坐标转换为一个字符串作为哈希表的 key,如果在遍历过程中两个棋子能够互相攻击,则说明 N 皇后问题不合法,返回 false。
- Java版本
import java.util.HashMap; import java.util.Map; public class QueensAttack { public static boolean canAttack(int x1, int y1, int x2, int y2) { // 判断两个棋子是否能够攻击 return x1 == x2 || y1 == y2; // 横纵坐标任意一个相同即为攻击范围 } public static boolean allQueensSafe(int n, int[] rows, int[] cols) { // 实现函数allQueensSafe,判断N皇后问题中的棋子是否互相攻击 Map<String, Boolean> board = new HashMap<>(); // 创建一个哈希表,用来储存棋盘中已经存在的棋子 for (int i = 0; i < n; i++) { // 遍历所有棋子 int row1 = i, col1 = cols[i]; board.put(row1 + "," + col1, true); // 将每个棋子的坐标存储到哈希表中 for (int j = i + 1; j < n; j++) { // 比较两个棋子的坐标是否可以互相攻击 int row2 = j, col2 = cols[j]; if (canAttack(row1, col1, row2, col2)) { // 如果两个棋子可以互相攻击,则N皇后问题不合法,返回false return false; } } } return true; // 如果所有棋子都不存在攻击范围,则说明N皇后问题合法,返回true } public static void main(String[] args) { int[] rows = {0, 3, 1, 4, 2}; // 棋子坐标,其中rows[i]表示第i个棋子所在的行(从0开始),cols[i]表示它所在的列 int[] cols = {0, 2, 4, 1, 3}; int n = rows.length; // 计算棋子数量 boolean ans = allQueensSafe(n, rows, cols); // 判断N皇后问题是否合法 if (ans) System.out.println("All queens are safe"); else System.out.println("Queens can attack each other"); } }
需要说明的是,在上述代码实现中,我们基于哈希表来判断是否存在攻击关系。具体而言,将每个棋子的坐标转换为一个字符串作为哈希表的 key,如果在遍历过程中两个棋子能够互相攻击,则说明 N 皇后问题不合法,返回 false。