队列广度优先搜索
1.地图包围圈 题目: 有一个长为m,宽为n的长方形地图,图上有一个不规则的小岛,小岛的海岸线被1标记出来了,也就是说小岛外面的0表示海水,小岛里面的0是陆地,请问小岛内被海岸线包围起来的0有多少个。已知m<100,n<100,且小岛外一定是海水包围着小岛的。 样例: 输入: 23 15 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 1 0 0 0 0 1 0 1 0 0 0 1 1 0 0 1 0 0 0 1 0 0 1 1 0 1 0 0 0 1 0 0 0 0 1 0 0 0 1 0 1 1 0 1 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 0 0 0 0 0 0 0 1 1 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 0 0 0 1 1 1 1 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 1 1 1 0 0 1 0 0 1 0 0 0 0 0 0 1 0 1 0 0 1 0 0 0 1 1 0 0 1 0 1 0 1 0 1 1 0 0 0 0 0 1 1 1 0 1 0 1 0 1 0 0 0 0 0 0 1 0 0 1 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 输出:110 #include
using namespace std; int main(){ int m,n,i,j,t,k,s=0,x,y; int a[100][100]={0},d[10000][2]={0}; int p[4][2]={{1,0},{0,-1},{-1,0},{0,1}}; scanf("%d %d",&m,&n); for(i=0;i
=0&&y>=0&&x
int ans,sx,sy,ex,ey; bool vis[9][9],map[9][9]={ 1,1,1,1,1,1,1,1,1, 1,0,0,1,0,0,1,0,1, 1,0,0,1,1,0,0,0,1, 1,0,1,0,1,1,0,1,1, 1,0,0,0,0,1,0,0,1, 1,1,0,1,0,1,0,0,1, 1,1,0,1,0,1,0,0,1, 1,1,0,1,0,0,0,0,1, 1,1,1,1,1,1,1,1,1 }; void dfs(int i,int j,int cnt) { if(i<0||i>8||j<0||j>8||vis[i][j]||map[i][j]||cnt>=ans)return; if(i==ex&&j==ey) { ans=cnt; return; } vis[i][j]=1; // 这个已经遍历了x` dfs(i,j-1,cnt+1); dfs(i-1,j,cnt+1); dfs(i,j+1,cnt+1); dfs(i+1,j,cnt+1); vis[i][j]=0; } int main() { int n; scanf("%d",&n); while(n--) { scanf("%d%d%d%d",&sx,&sy,&ex,&ey); ans=100; dfs(sx,sy,0); printf("%d\n",ans); } return 0; } 解法2:效率高,时间短 /*BFS广度优先搜索 */ #include
#include
using namespace std; #define N 9 typedef struct { // int x,y,cnt; }Node; int dir[4][2] = {{-1,0},{0,1},{1,0},{0,-1}}; int sx,sy,ex,ey; int mp[N][N] = { {1,1,1,1,1,1,1,1,1}, {1,0,0,1,0,0,1,0,1}, {1,0,0,1,1,0,0,0,1}, {1,0,1,0,1,1,0,1,1}, {1,0,0,0,0,1,0,0,1}, {1,1,0,1,0,1,0,0,1}, {1,1,0,1,0,1,0,0,1}, {1,1,0,1,0,0,0,0,1}, {1,1,1,1,1,1,1,1,1} }; int vis[N][N]; int bfs() { int Qx[10000]={0},Qy[10000]={0},Qcnt[10000]={0}; int k=0,px,py,pcnt,tmpx,tmpy,tmpcnt; Qx[0]=sx;Qy[0]=sy;Qcnt[0]=0; memset(vis,0,sizeof(vis)); vis[sx][sy] = 1; while(k>=0) { px= Qx[k]; py=Qy[k]; pcnt=Qcnt[k]; k--; if (px == ex && py == ey) return pcnt; for(int di=0;di<4;di++) { tmpx = px + dir[di][0]; tmpy = py + dir[di][1]; tmpcnt = pcnt + 1; if(tmpx>=0 && tmpx<=8 && tmpy>=0 && tmpy<=8 &&!vis[tmpx][tmpy] && !mp[tmpx][tmpy] ) { k++; Qx[k]=tmpx; Qy[k]=tmpy; Qcnt[k]=tmpcnt; vis[tmpx][tmpy] = 1; } } } return -1; } int main() { int t; scanf("%d",&t); while(t--) { scanf("%d%d%d%d",&sx,&sy,&ex,&ey); printf("%d\n",bfs()); } return 0; } 解法3: /*同样BFS广度优先搜索 只是用 队列数组Queue的入队和出队的封装函数,定义结点类型,从而减少编写代码量,更简洁 */ #include
#include
#include
using namespace std; #define N 9 typedef struct { int x,y,cnt; }Node; int dir[4][2] = {{-1,0},{0,1},{1,0},{0,-1}}; int sx,sy,ex,ey; int mp[N][N] = { {1,1,1,1,1,1,1,1,1}, {1,0,0,1,0,0,1,0,1}, {1,0,0,1,1,0,0,0,1}, {1,0,1,0,1,1,0,1,1}, {1,0,0,0,0,1,0,0,1}, {1,1,0,1,0,1,0,0,1}, {1,1,0,1,0,1,0,0,1}, {1,1,0,1,0,0,0,0,1}, {1,1,1,1,1,1,1,1,1} }; int vis[N][N]; int bfs() { queue
Q; Node tmp,p; p.x = sx; p.y = sy; p.cnt = 0; memset(vis,0,sizeof(vis)); vis[sx][sy] = 1; Q.push(p); while(!Q.empty()) { p = Q.front(); Q.pop(); if (p.x == ex && p.y == ey) return p.cnt; for(int di=0;di<4;di++) { tmp.x = p.x + dir[di][0]; tmp.y = p.y + dir[di][1]; tmp.cnt = p.cnt + 1; if(tmp.x>=0 && tmp.x<=8 && tmp.y>=0 && tmp.y<=8 &&!vis[tmp.x][tmp.y] && !mp[tmp.x][tmp.y] ) { Q.push(tmp); vis[tmp.x][tmp.y] = 1; } } } return -1; } int main() { int t; scanf("%d",&t); while(t--) { scanf("%d%d%d%d",&sx,&sy,&ex,&ey); printf("%d\n",bfs()); } return 0; } 3. 广度优先走迷宫找最短路径 #include
using namespace std; void EnQueue(int i,int j,int k); //入队一个节点 void DeQueue(int *i,int *j,int *k); //获取当前节点的序号和对应的迷宫坐标,然后出列 bool GetNextPos(int *i ,int *j,int count); //得到下一个邻接点的位置 void ShortestPath_BFS(int i,int j); //广度优先遍历寻找最短路径 void ShortestPath(); //输出最短路径 void Print(); //输出迷宫形状 int Map[10][10] = {{1,1,1,1,1,1,1,1,1,1},{1,0,0,1,0,0,0,1,0,1},{1,0,0,1,0,0,0,1,0,1},{1,0,0,0,0,1,1,0,0,1}, {1,0,1,1,1,0,0,0,0,1}, {1,0,0,0,1,0,0,0,0,1},{1,0,1,0,0,0,1,0,0,1},{1,0,1,1,1,0,1,1,0,1},{1,1,0,0,0,0,0,0,0,0},{1,1,1,1,1,1,1,1,1,1}}; struct Node { int parent_id; //保存父节点的位置 int node_id; //当前节点的序号,以便传递给孩子节点 int x,y; //当前结点对应的坐标 }Q[10*10]; //每个节点包含迷宫坐标、队列中的序号、父节点的序号,多个节点形成队列 int front = 0,rear = 0; //队列头指针和尾指针 int main() { cout<<"程序说明:"<<'\n'<<"1.输出路径为最短路径;"<<'\n'<<"2.默认的出口在最右下角,如有需要可以调整。"<<'\n'<<'\n'; cout<<"初始地图如下:"<
>i>>j; if(Map[i][j]) { cout<<"不能从该处出发,请重新输入!"<