搜索
bfs
1.求最小
2.基于迭代
Flood Fill
“洪水填充法”
对于一个凹凸的地形图,每次选择一个凹进去的格子(想象有一个无穷大的格子),那么水会慢慢覆盖掉周围所有的洼地。这个覆盖过程是按照bfs的顺序进行的。(你想按深度dfs顺序覆盖也没人拦你,只不过可能爆栈)
效果:可以在线性时间复杂度内,找到某个点所在的连通块。
池塘计数
#include <bits/stdc++.h>
using namespace std;
#define xx first
#define yy second
const int N = 1005;
/*wc,想用并查集,忍住了*/
int rx[10] = {-1, 1, 0, 0, 1, 1, -1, -1};
int ry[10] = {0, 0, -1, 1, 1, -1, 1, -1};
char mp[N][N];
int n, m, a[N][N], cnt = 0;
queue<pair<int, int> > q;
void bfs(int u, int v)
{
q.push(make_pair(u, v));
a[u][v] = ++ cnt;
while(!q.empty())
{
u = q.front().xx, v = q.front().yy;
q.pop();
for (int i = 0; i < 8; ++ i)
{
int nx = u + rx[i], ny = v + ry[i];
if(nx <= 0 || ny <= 0 || nx > n || ny > m) continue;
if(!a[nx][ny] && mp[nx][ny] == 'W') a[nx][ny] = cnt, q.push(make_pair(nx, ny));
}
}
return ;
}
int main()
{
scanf("%d %d", &n, &m);
for (int i = 1; i <= n; ++ i) scanf("%s", mp[i] + 1);
for (int i = 1; i <= n; ++ i)
{
for (int j = 1; j <= m; ++ j)
{
if(a[i][j] == 0 && mp[i][j] == 'W') bfs(i, j);
}
}
printf("%d", cnt);
return 0;
}
城堡问题
/*
(x, y) -> (x, y + 1) 没有4, 没有1 右
(x, y) -> (x, y - 1)没有1, 没有4 左
(x, y) -> (x + 1, y) 没有8 没有2 下
(x, y) -> (x - 1, y) 没有2 没有8 上
没有说明 & 的时候结果为0
*/
#include <bits/stdc++.h>
using namespace std;
#define xx first
#define yy second
const int N= 55;
int n, m, a[N][N], b[N][N], cnt = 0, ans = 0;
int rx[5] = {-1, 1, 0, 0};
int ry[5] = {0, 0, -1, 1};
int pdx[5] = {2, 8, 1, 4};
int pdy[5] = {8, 2, 4, 1};
queue<pair<int, int> > q;
void bfs(int u, int v)
{
int sum = 1;
q.push(make_pair(u, v));
b[u][v] = ++ cnt;
while(!q.empty())
{
u = q.front().xx, v = q.front().yy;
q.pop();
for (int i = 0; i < 4; ++ i)
{
int x = u + rx[i], y = v + ry[i];
if(x <= 0 || y <= 0 || x > n ||y > m || b[x][y]) continue;
if(!(a[u][v] & pdx[i]) && !(a[x][y] & pdy[i])) b[x][y] = cnt, q.push(make_pair(x, y)), sum ++;
}
}
ans = max(ans, sum);
return ;
}
int main()
{
scanf("%d %d", &n, &m);
for (int i = 1; i <= n; ++ i)
{
for (int j = 1; j <= m; ++ j) scanf("%d", &a[i][j]);
}
for (int i = 1; i <= n; ++ i)
{
for (int j = 1; j <= m; ++ j)
{
if(!b[i][j]) bfs(i, j);
}
}
printf("%d\n%d", cnt, ans);
return 0;
}
多源bfs
矩阵距离
这个题目需要我们求距离最近的1的曼哈顿距离。就相当于所有的1都是源点,然后求该点到源点的最短距离。直接把源点都放进初始的队列中就可以了。
#include <bits/stdc++.h>
using namespace std;
#define fir first
#define sec second
const int N = 1005;
int n, m, dis[N][N];
char a[N][N];
bool vis[N][N];
int rx[5] = {-1, 1, 0, 0};
int ry[5] = {0, 0, -1, 1};
int main()
{
scanf("%d %d", &n, &m);
queue<pair<int, int> > q;
for (int i = 1; i <= n; ++ i)
{
scanf("%s", a[i] + 1);
for (int j = 1; j <= m; ++ j)
{
if(a[i][j] == '1') vis[i][j] = 1, dis[i][j] = 0, q.push(make_pair(i, j));
}
}
while(!q.empty())
{
int x = q.front().fir, y = q.front().sec;
q.pop();
for (int i = 0; i < 4; ++ i)
{
int nx = x + rx[i], ny = y + ry[i];
if(nx <= 0 || ny <= 0 || nx > n || ny > m || vis[nx][ny]) continue;
vis[nx][ny] = 1;
q.push(make_pair(nx, ny));
dis[nx][ny] = dis[x][y] + 1;
}
}
for (int i = 1; i <= n; ++ i)
{
for (int j = 1; j <= m; ++ j)
{
printf("%d ", dis[i][j]);
}
printf("\n");
}
return 0;
}
最小步数模型
最小步数模型一般是对一个状态进行操作,求这个状态变成另外一个新状态所需要的最小的步数。
#include <bits/stdc++.h>
using namespace std;
int f[5][10] =
{
{7, 6, 5, 4, 3, 2, 1, 0},
{3, 0, 1, 2, 5, 6, 7, 4},
{0, 6, 1, 3, 4, 2, 5, 7}
};
char s[5] = {' ', 'A', 'B', 'C'};
map<int, int> vis, pre;
int n, g = 0;
vector<char> path;
struct node
{
int a[8], num;
}p;
queue<node> q;
void bfs()
{
p.num = 0;
for (int i = 0; i < 8; ++ i) p.a[i] = i, p.num = p.num * 10 + i;
vis[p.num] = -1, pre[p.num] = -1;
q.push(p);
while(!q.empty())
{
node x = q.front();
q.pop();
for (int i = 0; i < 3; ++ i)
{
node y; y.num = 0;
for (int j = 0; j < 8; ++ j)
{
y.a[j] = x.a[f[i][j]];
y.num = y.num * 10 + y.a[j];
}
if(!vis.count(y.num))
{
vis[y.num] = i + 1, pre[y.num] = x.num;
q.push(y);
}
}
if(vis.count(g)) break;
}
return ;
}
void dfs(int x)
{
if(x == -1) return ;
dfs(pre[x]);
path.push_back(s[vis[x]]);
}
int main()
{
int x;
for (int i = 0; i < 8; ++ i)
{
scanf("%d", &x);
g = g * 10 + (x - 1);
}
bfs();
dfs(g);
printf("%d\n", path.size() - 1);
for (int i = 1; i < path.size(); ++ i)
{
printf("%c", path[i]);
}
return 0;
}

浙公网安备 33010602011771号