题目
题目链接
题解DFS。
整体思路: 横向分块,如下: 我们只需要按连通块的序号去深搜即可,对于每个连通块,我们可以选择其中的任何一个空格作为放“車”的位置,或者选择不在这个连通块中放“車”。因此,我们的问题转化为在dfs中如何确定连通块,如何确定连通块中的哪个格子可以放,哪个格子不能放。
解决连通块的确定,只需要解决左端点和右端点的确定即可,那么我们不妨去遍历这一行,遇到洞就说明分开了两个连通块(不严谨的说)。对于确定好的一个连通块,我们对这个连通块中的空格再进行遍历,这次遍历的目的是为了确定连通块中的一个空格作为这个要选择的位置,将选中的位置进行标记,再就可以进行深搜下一个连通块了,同时不能忘记不选的情况,此时不需要对记录已放“車”数量的变量进行++
。
为了方便连通块的查找,我直接将dfs函数的第一个参数设置为行号,第二个参数设置为列号,这个列号对应的位置的左侧一定是一个洞,也就是说这个列号对应着一个连通块的左端点,从这个列向右侧遍历,遇到洞就说明这个连通块的右端点也确定了,就可以进行选择空格放“車”了。
我们进行标记的用处在于,每次要确定一个连通块中的空格能不能选时,需要向上面已经搜完的行去遍历。我就看看我如果选这个位置的空格,那么它上面会不会已经有“車”了,其实有“車”也不要紧,先遇到洞也可以隔开俩“車”的攻击。通过从当前列向列号小的列遍历,看是不是满足条件,满足条件才能选中当前这个位置的空格。
注意如何变行。
代码#include
using namespace std;
const int N = 10;
int n, ans, bound, sum, mp[N][N], vis[N][N];
bool check(int row, int col) {
int i = row-1; // 从上一行查起
for(;i >= 0;i --) {
if(vis[i][col]) break; // 如果遇到車了,就跳出
if(!mp[i][col]) {i = -1; break;} // 如果遇到洞了,说明没有車在攻击范围内,i=-1是为了统一返回的条件表达式
}
return i = bound) {ans++; return ;}
if(col >= n) row ++, col = 0; // 变行操作
if(row >= n) return ;
int i = col;
for(;i n;
for(int i = 0;i mp[i][j];
for(int i = 1;i
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?