因为周六举行月赛,写几个经典的BFS DFS 供大家参考,代码是以前写的不是很简洁,有不懂的可留言。
注:写搜索时一定要记得访问标记,以免访问过的点再次访问,出现死循环等情况。
数据范围比较小,可以用递归,代码简洁些;
#include "stdio.h"
#define M 82
int dx[] = {0,1,0,-1}; //方向数组
int dy[] = {1,0,-1,0};
int DFS (int x,int y);
int n;
char map[M][M];
int DFS (int x,int y)
{
int i,X,Y,flag;
if (x == n&& y== n)//找到出口,返回1
{
map[x][y] = '#'; //标记路径
return 1;
}
if (map[x][y] == '1')
return 0;
map[x][y] = '*';//访问标记 以免重复访问
flag = 0;
for (i = 0; i < 4; i ++)
{
X = x + dx[i];//查找四个方向
Y = y + dy[i];
if (map[X][Y] == '1'||map[X][Y] == '*') //该点不可走,或已访问过
continue;
else if (DFS(X,Y) == 1) flag = 1;
}
if (flag == 0) //回退输出路径
map[x][y] = '0';
else
map[x][y] = '#';
return flag;
}
int main ()
{
int i,j,x,y;
scanf ("%d %d %d",&n,&y,&x);
for (i = 1; i <= n; i ++)
for (j = 1; j <= n; j ++)
{
getchar ();
scanf ("%c",&map[i][j]);
}
for (i = 0; i <=n+1; i ++) //给图加个框,就不必再判断点是否出界
for (j = 0; j<=n+1; j ++)
if (j == 0||i==0||j==n+1||i==n+1)
map[i][j] = '1';
if (DFS(x,y) == 1)
{
printf ("Found\n");
for (i = 1; i <= n; i ++)
{
for (j =1; j <= n; j++)
{
if (j == n)
printf ("%c",map[i][j]);
else
printf ("%c ",map[i][j]);
}
printf ("\n");
}
}
else
printf ("Not Found\n");
return 0;
}
数据范围比较大,用递归用会RE,所以自己写栈或队列,这里用BFS做
#include "stdio.h"
#include "string.h"
#define M 1050
int dx[] = {-1,0,1,0};
int dy[] = {0,-1,0,1};
//int dir[4][2] = {{-1,0},{0,-1},{1,0},{0,1}}; 也可以这样写
int flow;
struct back
{
int x0,y0;
int n; //记录某点的前驱 记录路径用的
} b[M*M];
char map[M][M];
int BFS (int X,int Y,int m,int n)
{
int front = 0,num = 0;
int rear = 0;
b[0].x0 = X;
b[0].y0 = Y;
while (front != rear)
{
flow = front;
X = b[front].x0;//从队列中取出点
Y = b[front].y0;
map[X][Y] = '*';//访问标记
front ++;
for (int i = 0; i < 4; i ++)//4个方向搜索
{
int x = X + dx[i];
int y = Y + dy[i];
if (x < 1|| y < 1||x>m||y>n) //找到出口,返回1
return 1;
else if (map[x][y] == '.') //可以走,进队列
{
rear ++;
b[rear].x0 = x;
b[rear].y0 = y;
b[rear].n = front;
map[x][y] = '*';
}
}
}
return 0;
}
int main ()
{
int i,j,k,m,n,x,y,t;
long count;
char str[M];
while (scanf ("%d %d",&m,&n))
{
if (m==0&&n==0)
break;
getchar ();
count = 1;
for (i = 1; i <= m; i ++)//读入地图
{
k = 0;
j = 1;
gets (str);
while (str[k] != '\0')
{
map[i][j] = str[k++];
if (map[i][j] == 'X')
{
x = i;
y = j;
}
j ++;
}
memset (str,'\0',sizeof (str));
}
if (BFS (x,y,m,n))
{
map[x][y] = 'X';
while (1) //输出路径
{
if (b[flow].x0==x&&b[flow].y0==y)
break;
map[b[flow].x0][b[flow].y0] = 'w';
flow = b[flow].n;
count ++; //记录步数
}
printf ("You can escaped in %ld minute(s).\n",count);
for (i = 1; i <= m; i ++)
{
for (j = 1; j <= n; j ++)
{
if (map[i][j] == '*')
printf (".");
else
printf ("%c",map[i][j]);
}
printf ("\n");
}
printf ("\n");
}
else
printf ("My good friend, may God bless you!\n\n");
memset (map,'\0',sizeof(map));
}
return 0;
}
这题是BFS与DFS结合,也得自己写栈,否则会超时,这里用到一个就 flood fill算法,这里不多说,百度之;其实就是BFS。
#include "stdio.h"
#define M 1005
char map[M][M];
int dx0[] = {-1,0,1,0};
int dy0[] = {0,-1,0,1};
int dx[] = {-1,-1,0,1,1,1,0,-1};
int dy[] = {0,-1,-1,-1,0,1,1,1};
struct node
{
int x,y;
} visit[1000000],find[1000000];
void BFS(int x,int y,int n,int m)
{
int front,rear,i,x0,y0;
front = rear = 0;
find[++rear].x = x;
find[rear].y = y;
while (front != rear)
{
x0 = find[front].x;
y0 = find[front++].y;
if (map[x0][y0] == '0')//把原来是‘0’的地方变为‘#’
map[x0][y0] = '#';
for (i = 0; i < 4; i ++)
{
x = x0+dx0[i];
y = y0+dy0[i];
if (x<0||x>=n||y<0||y>=m)
continue;
if (map[x][y] == '1')
{
map[x][y] = '2';//1 变为 2
continue;
}
if (map[x][y] == '0')
{
map[x][y] = '#';
find[++rear].x = x;
find[rear].y = y;
}
}
}
}
void DFS (int x,int y,int n,int m)//DFS 查找有多少个用2组成的图形
{
int i,x0,y0;
int top = 0;
visit[top].x = x;
visit[top++].y = y;
while (top >= 0)
{
x0 = visit[--top].x;
y0 = visit[top].y;
map[x0][y0] = '*';
for (i = 0; i < 8; i ++)
{
x = x0+dx[i];
y = y0+dy[i];
if (x > 0&&x < n&&y>0&&y
{
visit[top].x = x;
visit[top++].y = y;
}
}
}
}
int main ()
{
int n,m,n0,m0,i,j,count = 0;
scanf ("%d %d",&n0,&m0);
n = n0+2;
m = m0+2;
getchar ();
for (i = 1; i <= n0; i ++)
gets (map[i]+1);
for (i = 0; i <= n0+1; i ++)
for (j = 0; j <= m0+1; j ++)
if (i==0||i==n0+1||j==0||j==m0+1)//加框,以原图外一点为起点 (自己想想为什么)
map[i][j] = '0';
BFS(0,0,n,m);//bfs 进行涂色
for (i = 0; i < n; i ++)
for (j = 0; j < m; j ++)
if (map[i][j] == '2')//找出有多少个图形
{
count ++;
DFS (i,j,n,m);
}
printf ("There are %d shape elements\n",count);
return 0;
}