BFS: 刷题专用
BFS 刷题
看了一天的图方面的东西,这个东西,真的是,思路都懂,但是实现起来,哈哈哈哈哈哈哈,一直处于懵逼的状态,所以就找点题刷吧,加强理解与应用,突然有点理解高中的应试教育了。
POJ 3984
题目描述
它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。
题目链接:http://poj.org/problem?id=3984
这个题,其实就是一个基本的BFS搜索,找最短路线,对于BFS。从出发点开始,第一次遍历到终点时过的那条路径就是最短的路径。因为这条路径没有多绕一个不相关节点啊,所以它是最短的。但是这个题并不是简单的去求这条路有多长,他得求出路径,所以需要存储遍历时候的路径的顺序。
#include <stdio.h>
#include <stdbool.h>
struct Node{
int x, y;
int pre;
int level;
};
int pos[4][2] = {{0,1},{0,-1},{1,0},{-1,0}}; //右,左,上,下
int main() {
int i, j;
int num[5][5] = {0};
struct Node queue[30]; //建立队列
struct Node result[30];
int rear = 0;
int head = 0;
int visit[5][5] = {0};
struct Node root;
int cnt = 0;
bool flag = false;
// printf("你好");
for (i = 0; i < 5; i++)
for (j = 0; j < 5; j++) {
scanf("%d", &num[i][j]);
}
queue[rear].x = 0; //第一个元素入队
queue[rear].y = 0;
queue[rear].level = 0;
queue[rear].pre = -1;
result[cnt++] = queue[rear];
rear += 1;
visit[0][0] = 1;
int parent;
while(rear != head){ //队不为空;
root = queue[head++]; //出队;
i = -1;
parent = root.level; //获取层次
if(root.x == 4 && root.y == 4){
flag = true;
break;
}
while (i < 3){//四个方向
i += 1;
int x = root.x + pos[i][0];
int y = root.y + pos[i][1];
if(x < 0 || y< 0 || y > 4 || x > 4 || visit[x][y] == 1 || num[x][y] == 1)
continue;
//printf("%d ", rear);
queue[rear].x = x;
queue[rear].y = y;
queue[rear].pre = parent;
queue[rear].level = cnt; //他的层次;
result[cnt++] = queue[rear];
visit[x][y] = 1;
rear += 1;
}
}
cnt = parent;
i = 0;
while(cnt != -1){
queue[i++] = result[cnt];
cnt = result[cnt].pre;
}
for(i = i - 1; i > 0; i--)
printf("(%d, %d)\n",queue[i].x,queue[i].y);
printf("(4, 4)");
}
POJ 1979
题目描述
There is a rectangular room, covered with square tiles. Each tile is colored either red or black. A man is standing on a black tile. From a tile, he can move to one of four adjacent tiles. But he can't move on red tiles, he can move only on black tiles.
Write a program to count the number of black tiles which he can reach by repeating the moves described above.
就只是简简单单的遍历图的过程,记录最多可以遍历多少个点
题目链接http://poj.org/problem?id=1979
#include<stdio.h>
#include<stdlib.h>
#include <stdbool.h>
struct Node
{
int x;
int y;
int pre;
};
int pos[4][2] = {{0,1},{0,-1},{1,0},{-1,0}}; //上下左右四个方向
int main()
{
int m,n;
char arr[1000][1000];
while(true)
{
scanf("%d %d",&m,&n);
if(m == 0 && n == 0)
return 0;
int i = 0;
int j = 0;
int begin_x;
int begin_y;
bool visit[1000][1000] = {false}; //用来标志还没被访问;
struct Node queue[1000]; //用队列来存储节点;
int rear = 0;
int head = 0;
int cnt = 0;
getchar();
for(i = 0; i < n; i++)
{
for(j = 0; j < m; j++)
{
scanf("%c",&arr[i][j]);
if(arr[i][j] == '@')
{
begin_x = i;
begin_y = j;
}
}
getchar();
}
queue[rear].x = begin_x;
queue[rear].y = begin_y;
rear += 1;
cnt += 1;
visit[begin_x][begin_y] = true;
while(head != rear){
struct Node root = queue[head++];
for(i = 0; i < 4; i++){
int x = root.x + pos[i][0];
int y = root.y + pos[i][1];
if(x < 0 || y < 0 || x >= n || y >= m || visit[x][y] || arr[x][y] == '#')
continue;
cnt += 1;
queue[rear].x = x;
queue[rear].y = y;
rear += 1;
visit[x][y] = true;
}
}
printf("%d\n",cnt);
}
return 0;
}