周赛的第二题一般的会比较有意思,来看题目(由于样例说明比较详细,题目较短,所以题目就直接复制了)
题目如下:
在一个 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++的代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 };
周赛不易,诸君共勉!