给定一组棋子的坐标,判断是否可以互相攻击。如果两个棋子的横纵坐标任意一个相同,则认为它们可以互相攻击。(提示:使用哈希表)
简介:给定一组棋子的坐标,判断是否可以互相攻击。如果两个棋子的横纵坐标任意一个相同,则认为它们可以互相攻击。(提示:使用哈希表)
算法思路
算法思路:
- 首先我们需要读取所有的棋子坐标,并将其存储在一个哈希表中。其中,哈希表的 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。