1.拯救小哈之BFS
具体题目描述 点击这里
参考代码
#include<iostream>
#include<queue>
using namespace std;
struct node {
int x;
int y;
int f;
int s;//步数
};
int NEXT[4][2] = { {0,1},{1,0},{0,-1},{-1,0} };
int n, m, startx, starty, p, q, tx, ty, flag;
queue<node> que;
int main()
{
int a[51][51] = { 0 }, book[51][51] = { 0 };
cin >> n >> m;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++) {
cin >> a[i][j];
}
}
cin >> startx >> starty >> p >> q;
node nd;
nd.x = startx;
nd.y = starty;
nd.f = 0;
nd.s = 0;
que.push(nd);
book[startx][starty] = 1;
flag = 0;//标记是否到达目标点
//当队列不为空的时候循环
while (!que.empty()) {
//四个方向
node n1 = que.front();
for (int i = 0; i <= 3; i++) {
tx = n1.x + NEXT[i][0];
ty = n1.y + NEXT[i][1];
//是否越界
if (tx < 1 || tx > n || ty <1 || ty > m) {
continue;
}
if (a[tx][ty] == 0 && book[tx][ty] == 0) {
book[tx][ty] = 1;
node n2;
n2.x = tx;
n2.y = ty;
n2.f = n1.f;
n2.s = n1.s + 1;
que.push(n2);
}
//如果到目标点了,停止扩展,结束循环
if (tx == p && ty == q) {
flag = 1;
break;
}
}
if (flag) {
break;
}
//当前点扩展结束,弹出改点.
que.pop();
}
if (que.size() > 0) {
cout << que.back().s << endl;
}
return 0;
}
2.炸弹人
游戏简述
通过放置炸弹的方法来消灭敌人,炸弹只能放置在空地上,炸弹可以向上下左右四个方向炸开,碰到敌人可以消灭,但是碰到墙则停止这个炸弹在这个方向上的威力。
现在有个特殊的关卡,只有一枚炸弹(炸弹威力大杀伤距离足够强威力足够大),请问这个炸弹放置在地图上的哪个空位上,能够消灭最多数量的敌人。
先将地图模型化,把墙用符号“#”表示,敌人用大写字母G表示,空地用英文点号“.”表示,整张地图可以抽象成一个二维数组。接下来我们使用BFS解决.
参考代码
#include<iostream>
#include<queue>
using namespace std;
struct node {
int x;
int y;//横纵坐标
};
char a[25][25];//用来存储地图
int sum1, x, y,max1,mx,my,n,m,startx,starty,tx,ty;
queue<node> que;
int book[25][25];//定义一个标记
int NEXT[4][2] = { {0,1},{1,0},{0,-1},{-1,0} };//方向数组
int getnum(int i, int j) {
int sum;
sum = 0;//用于计数
x = i;
y = j;
//向上统计 可以消灭的敌人
while (a[x][y] != '#') {//判断该点是不是墙
if (a[x][y] == 'G') {
sum++;
}
x--;
}
//向下统计
x = i;
y = j;
while (a[x][y] != '#') {
if (a[x][y] == 'G') {
sum++;
}
x++;
}
//向左统计
x = i;
y = j;
while (a[x][y]!='#')
{
if (a[x][y] == 'G') {
sum++;
}
y--;
}
//向右统计
x = i;
y = j;
while (a[x][y] != '#')
{
if (a[x][y] == 'G') {
sum++;
}
y++;
}
return sum;
}
int main() {
cin >> n >> m >> startx >> starty;
for (int i = 0; i < n; i++) {
cin >> a[i];
}
//队列初始化
node nd;
nd.x = startx;
nd.y = starty;
que.push(nd);
max1 = getnum(startx, starty);
mx = startx;
my = starty;
//队列不为空时进行循环
while (!que.empty()) {
//枚举四个方向
node nd2 = que.front();
for (int i = 0; i <= 3; i++) {
sum1 = 0;
tx = nd2.x + NEXT[i][0];
ty = nd2.y + NEXT[i][1];
if (tx < 0 || tx > n - 1 || ty < 0 || ty > m - 1) {//判断是否越界
continue;
}
if (a[tx][ty] == '.' && book[tx][ty] == 0) {
book[tx][ty] = 1;
node nd3;
nd3.x = tx;
nd3.y = ty;
que.push(nd3);
sum1 = getnum(tx, ty);
if (sum1 > max1) {
max1 = sum1;
mx = tx;
my = ty;
//cout << "哈哈哈" << max1 << endl;
}
}
}
que.pop();
}
cout << "将炸弹放在:" << mx <<" "<< my << "处,最多可以消灭的敌人是" << max1 << endl;
return 0;
}
/*
13 13 3 3
#############
#GG.GGG#GGG.#
###.#G#G#G#G#
#.......#..G#
#G#.###.#G#G#
#GG.GGG.#.GG#
#G#.#G#.#.#.#
##G...G.....#
#G#.#G###.#G#
#G#.#G#G#.#G#
#GG.GGG#G.GG#
#GG.GGG#G.GG#
#############
*/
运行结果
可以看出BFS的核心是:搜索所有的空白快,完毕后输出最小的即可.
该题也可使用DFS进行解决
参考代码2
#include<iostream>
using namespace std;
char a[25][25];//用来存储地图
int sum1, x, y, max1, mx, my, n, m, startx, starty, tx, ty;
int book[25][25];//定义一个标记
int NEXT[4][2] = { {0,1},{1,0},{0,-1},{-1,0} };//方向数组
int getnum(int i, int j) {
int sum;
sum = 0;//用于计数
x = i;
y = j;
//向上统计可以消灭的敌人
while (a[x][y] != '#') {//判断的点是不是墙
if (a[x][y] == 'G') {
sum++;
}
x--;
}
//向下统计
x = i;
y = j;
while (a[x][y] != '#') {
if (a[x][y] == 'G') {
sum++;
}
x++;
}
//向左统计
x = i;
y = j;
while (a[x][y] != '#')
{
if (a[x][y] == 'G') {
sum++;
}
y--;
}
//向右统计
x = i;
y = j;
while (a[x][y] != '#')
{
if (a[x][y] == 'G') {
sum++;
}
y++;
}
return sum;
}
void dfs(int x, int y) {
sum1 = getnum(x, y);
if (sum1 > max1) {
max1 = sum1;
mx = x;
my = y;
}
for (int i = 0; i <= 3; i++) {
sum1 = 0;
tx = x+ NEXT[i][0];
ty = y + NEXT[i][1];
if (tx < 0 || tx > n - 1 || ty < 0 || ty > m - 1) {
continue;
}
//判断是否走过
if (a[tx][ty] == '.' && book[tx][ty] == 0) {
book[tx][ty] = 1;
dfs(tx, ty);
}
}
return;
}
int main() {
cin >> n >> m >> startx >> starty;
for (int i = 0; i < n; i++) {
cin >> a[i];
}
book[startx][starty] = 1;
max1 = getnum(startx, starty);
mx = startx;
my = starty;
dfs(startx, starty);
cout << "将炸弹放在:" << mx << " " << my << "处,最多可以消灭的敌人是" << max1 << endl;
return 0;
}
DFS解决的话,在于只要遍历过就行,无需回溯.
3.宝岛冒险
小哼通过秘密方法得到了一张不完整的钓鱼岛航拍地图。钓鱼岛由一个主岛和一些附属岛屿组成,小哼决定去钓鱼岛冒险。下面这个 10 * 10 的二维码矩阵就是钓鱼岛的航拍地图。图中数字代表海拔,0 表示海洋,1~9 表示陆地。小哼的飞机将会在(6,8)处,现在需要计算出小哼落地所在岛屿的面积(即有多少个格子)。
1 2 1 0 0 0 0 0 2 3
3 0 2 0 1 2 1 0 1 2
4 0 1 0 1 2 3 2 0 1
3 2 0 0 0 1 2 4 0 0
0 0 0 0 0 0 1 5 3 0
0 1 2 1 0 1 5 4 3 0
0 1 2 3 1 3 6 2 1 0
0 0 3 4 8 9 7 5 0 0
0 0 0 3 7 8 6 0 1 2
0 0 0 0 0 0 0 0 1 0
参考代码1–DFS
#include<iostream>
using namespace std;
int startx, starty,tx,ty,sum;
int NEXT[4][2] = { {0,1},{1,0},{0,-1},{-1,0} };
int book[13][13], map[13][13],total= 1;
//深搜
void dfs(int x, int y) {
for (int i = 0; i < 4; i++) {
tx = x + NEXT[i][0];
ty = y + NEXT[i][1];
//判断是否越界
if (tx < 1 || tx > 10 || ty < 1 || ty > 10) {
continue;
}
//判断是否是陆地
if (map[tx][ty] >= 1 && map[tx][ty] <= 9 && !book[tx][ty]) {
book[tx][ty] = 1;
total++;
dfs(tx, ty);
}
}
}
int main()
{
for (int i = 1; i <= 10; i++) {
for (int j = 1; j <= 10; j++) {
cin >> map[i][j];
}
}
book[6][8] = 1;
dfs(6, 8);
cout << total << endl;
return 0;
}
参考代码2—BFS
#include<iostream>
#include<queue>
using namespace std;
struct node {
int X;
int Y;
};
queue<node> que;
int startx, starty,tx,ty,sum;
int NEXT[4][2] = { {0,1},{1,0},{0,-1},{-1,0} };
int book[13][13], map[13][13],total= 1;
void bfs(int x, int y) {
node nd;
nd.X = x;
nd.Y = y;
que.push(nd);
while (!que.empty()) {
node nd2;
nd2 = que.front();
for (int i = 0; i <= 3; i++) {
tx = nd2.X + NEXT[i][0];
ty = nd2.Y + NEXT[i][1];
//判断是否越界
if (tx < 1 || tx > 10 || ty < 1 || ty > 10) {
continue;
}
if (map[tx][ty] >= 1 && map[tx][ty] <= 9 && !book[tx][ty]) {
node nd3;
nd3.X = tx;
nd3.Y = ty;
que.push(nd3);
book[tx][ty] = 1;
total++;
}
}
que.pop();
}
}
int main()
{
for (int i = 1; i <= 10; i++) {
for (int j = 1; j <= 10; j++) {
cin >> map[i][j];
}
}
book[6][8] = 1;
bfs(6, 8);
cout << total << endl;
return 0;
}
/*
1 2 1 0 0 0 0 0 2 3
3 0 2 0 1 2 1 0 1 2
4 0 1 0 1 2 3 2 0 1
3 2 0 0 0 1 2 4 0 0
0 0 0 0 0 0 1 5 3 0
0 1 2 1 0 1 5 4 3 0
0 1 2 3 1 3 6 2 1 0
0 0 3 4 8 9 7 5 0 0
0 0 0 3 7 8 6 0 1 2
0 0 0 0 0 0 0 0 1 0
38
*/