周赛的第二题一般的会比较有意思,来看题目(由于样例说明比较详细,题目较短,所以题目就直接复制了)
题目如下:
在一个 8x8 的棋盘上,放置着若干「黑皇后」和一个「白国王」。
「黑皇后」在棋盘上的位置分布用整数坐标数组 queens 表示,「白国王」的坐标用数组 king 表示。
「黑皇后」的行棋规定是:横、直、斜都可以走,步数不受限制,但是,不能越子行棋。
请你返回可以直接攻击到「白国王」的所有「黑皇后」的坐标(任意顺序)。
样例如下:



这道题就是简单的模拟而已,只需要检测以king为中心的米字型里第一次出现的queen,计数即可。比较麻烦的是如何检测king的米字呢?
通过观察如果以king为坐标轴中心,向下、向右分别为 x,y 的正方向,那么它周围的格子的坐标就会是这样的:
(-1, -1) (-1,0) (-1,1)
(0,-1) (0, 0) (0,1)
(1,-1) (1, 0) (-1,-1)
得出这个九宫图那就之后题目就变得无比简单了,一层for控制循环方向,另一层for控制在该方向的循环的次数,记得确定溢出条件。
代码大概是这样子的
for (int i = 0; i < 8; i++)//方向
{
for (int x = king[0], y = king[1]; (x >= 0 && x < 8) && (y >= 0 && y < 8); x+=step_x[i], y+=step_y[i])//检测
{
……
}
}
其实这块基本就是核心了其余的就是判断成功后计数,其它细节自行填充。
最后贴一下c++的代码

1 /**
2 * @brief leetcode 158.2
3 * @note 注意控制循环范围
4 * @author 杨文蓁的小迷弟
5 */
6 class Solution
7 {
8 //x、y的跳变步长
9 const int step_x[8] = {-1, -1, -1, 0, 0, 1, 1, 1};
10 const int step_y[8] = {-1, 0, 1, -1, 1, -1, 0, 1};
11
12 public:
13 vector<vector<int>> queensAttacktheKing(vector<vector<int>> &queens, vector<int> &king)
14 {
15 //打表
16 bool map[8][8];
17 memset(map, 0, sizeof(map));
18 for (auto xy : queens)
19 {
20 map[xy[0]][xy[1]] = 1;
21 }
22
23 vector<vector<int>> ans;
24 vector<int> temp;
25
26 //搜索
27 for (int i = 0; i < 8; i++)
28 {
29 for (int x = king[0], y = king[1]; (x >= 0 && x < 8) && (y >= 0 && y < 8); x += step_x[i], y += step_y[i])
30 {
31 if (map[x][y])
32 {
33 temp.clear();
34 temp.push_back(x);
35 temp.push_back(y);
36 ans.push_back(temp);
37 break; //找到最近的queen;
38 }
39 }
40 }
41 return ans;
42 }
43 };
周赛不易,诸君共勉!
