题解 | #牛吃草问题#
牛吃草问题
https://www.nowcoder.com/practice/c6e33216019a4ea9bf4015e9868dd225
八皇后问题:
解题思路:
- 使用一个向量`cols`表示 `row`行放置了`col`列的牛; (也就是说[-1, 1,....,] 那个1表示在第二行的第一列放置了牛)
- 遍历每一行 row
- 在行内遍历每一个位置 col
- 判断(row,col)位置上是否能够放牛
- 查看cols的0~row-1的位置是否和(row,col)冲突
- cols[i] = col 肯定不可以嘛,别人已经占了这个位置了
- abs(cols[i] - col) = abs(i-row) 这个是嘛意思?
- $\frac{abs(cols[i] - col)}{abs(i-row)} = 1$懂了吧,就是斜率为1,对角线上哪些位置的
- 能放牛就放上去
- 不能就返回false
- 记得回溯回去
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param n int整型
* @return int整型
*/
// 检查当前位置是否可以放牛
bool isValid(vector<int>&cols,int row,int col){
// 检查row行,col列位置是否可以放置牛
for(int i=0;i<row;++i){
// 如果i行已经在col位置放了牛
// 或者i行放置的牛的位置在对角线上(斜率为1)
if(cols[i] == col || abs(cols[i] - col) == abs(i-row)){
return false;
}
}
return true;
}
void backtrack(vector<int>&cols,int row,int &count){
// cols的index表示行,值表示在第几列放了牛
int n = cols.size();
// 放置的牛的数量等于n,表示该位置合理
if(row == n){
count++;
return;
}
// 遍历每一列,看是否能够放牛
for(int col=0;col<n;col++){
if(isValid(cols,row,col)){
// 如果可以放牛就放上
cols[row] = col;
// 下一个位置是行数加1
backtrack(cols,row+1,count);
// 回溯回来
cols[row] = -1;
}
}
}
int totalNCow(int n) {
// 八皇后问题
vector<int> cols(n,-1); // 记录每一行中放牛的列索引
int count = 0;
backtrack(cols,0,count);
return count;
}
};
