1.油田连通块
链接地址:地址
递归DFS
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 using namespace std; 6 char map[110][110]; 7 bool vis[110][110]={0};//布尔类型减少内存浪费 8 int orient[8][2]={1,1,1,0,1,-1,0,1,0,-1,-1,1,-1,0,-1,-1}; 9 //八个方向的遍历 10 int m,n; 11 12 void DFS(int x,int y) 13 { 14 if(x<0||x>=m||y<0||y>=n) 15 return ; 16 if(vis[x][y]==1||map[x][y]!='@') 17 return ; 18 vis[x][y]=1; 19 20 for(int i=0;i<8;i++) 21 { 22 DFS(x+orient[i][0],y+orient[i][1]); 23 } 24 } 25 26 int main() 27 { 28 while(scanf("%d%d",&m,&n)&&m!=0) 29 { 30 memset(vis,0,sizeof(vis)); 31 int count=0; 32 for(int i=0;i<m;i++) 33 scanf("%s",map[i]); 34 for(int i=0;i<m;i++) 35 for(int j=0;j<n;j++) 36 { 37 if(vis[i][j]==0&&map[i][j]=='@') 38 { 39 DFS(i,j); 40 count++;//计数器 41 } 42 } 43 printf("%d ",count);//不用cout没有追求代码速度,而是追求运行速度 44 } 45 return 0; 46 }
2.Knight Moves
链接地址:链接
单向BFS
a.有返回值类型
1 #include <iostream> 2 #include <algorithm> 3 #include <cstdio> 4 #include <cstring> 5 #include <queue> 6 using namespace std; 7 //单向BFS实现,注意队列的使用 8 bool vis[310][310]={0}; 9 int orient[8][2]={{1,2},{2,1},{-2,1},{-1,2},{-2,-1},{-1,-2},{1,-2},{2,-1}}; 10 int l; 11 typedef struct node 12 { 13 int x,y,step; 14 }node; 15 16 bool check(int x,int y) 17 { 18 if(x<0||x>=l||y<0||y>=l) 19 return false; 20 return true; 21 22 } 23 int BFS(int x1,int y1,int x2,int y2) 24 { 25 queue<node>Q;//注意队列的清空 26 node temp; 27 temp.x=x1,temp.y=y1,temp.step=0; 28 Q.push(temp); 29 vis[x1][y1]=1; 30 while(!Q.empty()) 31 { 32 temp=Q.front(); 33 Q.pop(); 34 if(temp.x==x2&&temp.y==y2)//判断弹出条件 35 return temp.step; 36 for(int i=0;i<8;i++) 37 { 38 node Next; 39 Next.x=temp.x+orient[i][0]; 40 Next.y=temp.y+orient[i][1]; 41 Next.step=temp.step+1; 42 if(check(Next.x,Next.y)&&vis[Next.x][Next.y]==0) 43 { 44 45 vis[Next.x][Next.y]=1; 46 Q.push(Next); 47 48 } 49 } 50 } 51 return 0;//欺骗函数的返回,摆设 52 } 53 int main() 54 { 55 int t,x1,y1,x2,y2; 56 cin>>t; 57 while(t--) 58 { 59 cin>>l; 60 cin>>x1>>y1>>x2>>y2; 61 memset(vis,0,sizeof(vis)); 62 printf("%d ",BFS(x1,y1,x2,y2)); 63 64 65 } 66 return 0; 67 }
b.无返回值类型
1 #include <iostream> 2 #include <algorithm> 3 #include <cstdio> 4 #include <cstring> 5 #include <queue> 6 using namespace std; 7 8 bool vis[310][310]={0}; 9 int orient[8][2]={{1,2},{2,1},{-2,1},{-1,2},{-2,-1},{-1,-2},{1,-2},{2,-1}}; 10 int l; 11 typedef struct node 12 { 13 int x,y,step; 14 }node; 15 16 bool check(int x,int y) 17 { 18 if(x<0||x>=l||y<0||y>=l) 19 return false; 20 return true; 21 22 } 23 void BFS(int x1,int y1,int x2,int y2) 24 { 25 queue<node>Q; 26 node temp; 27 temp.x=x1,temp.y=y1,temp.step=0; 28 Q.push(temp); 29 vis[x1][y1]=1; 30 while(!Q.empty()) 31 { 32 temp=Q.front(); 33 Q.pop(); 34 if(temp.x==x2&&temp.y==y2) 35 { 36 printf("%d ",temp.step);//直接进行输出会节省时间 37 } 38 for(int i=0;i<8;i++) 39 { 40 node Next; 41 Next.x=temp.x+orient[i][0]; 42 Next.y=temp.y+orient[i][1]; 43 Next.step=temp.step+1; 44 if(check(Next.x,Next.y)&&vis[Next.x][Next.y]==0) 45 { 46 47 vis[Next.x][Next.y]=1; 48 Q.push(Next); 49 50 } 51 } 52 } 53 //return 0; 54 } 55 int main() 56 { 57 int t,x1,y1,x2,y2; 58 cin>>t; 59 while(t--) 60 { 61 cin>>l; 62 cin>>x1>>y1>>x2>>y2; 63 memset(vis,0,sizeof(vis)); 64 BFS(x1,y1,x2,y2); 65 } 66 return 0; 67 }
双向BFS
1 #include <iostream> 2 #include<algorithm> 3 #include <cstdio> 4 #include <cstdlib> 5 #include <cstring> 6 #include <queue> 7 using namespace std; 8 const int N = 310; 9 int l; 10 int vis[N][N]; 11 int dis[N][N]; 12 int orient[8][2]={{1,2},{1,-2},{2,1},{2,-1},{-2,1},{-2,-1},{-1,2},{-1,-2}}; 13 typedef struct node 14 { 15 int x,y; 16 }node; 17 void dBFS(int x1,int y1,int x2,int y2) 18 { 19 if(x1==x2&&y1==y2)//注意相等条件的弹出 20 { 21 printf("0 "); 22 return ; 23 } 24 queue<node>Q; 25 node front,behind;//用front,behind是为了复习的时候好理解 26 front.x=x1,front.y=y1; 27 behind.x=x2,behind.y=y2; 28 vis[x1][y1]=1;//从头开始的标记1 29 vis[x2][y2]=2;//从尾开始的标记2 30 Q.push(front); 31 Q.push(behind); 32 while(!Q.empty()) 33 { 34 front=Q.front(); 35 Q.pop();//注意每次的弹出 36 37 for(int i=0;i<8;i++) 38 { 39 behind.x=front.x+orient[i][0]; 40 behind.y=front.y+orient[i][1]; 41 if(behind.x>=0&&behind.x<l&&behind.y>=0&&behind.y<l)//当吧判断条件写成这样可以减少 42 { //进入函数所浪费的时间 43 if(!vis[behind.x][behind.y]) 44 { 45 vis[behind.x][behind.y]=vis[front.x][front.y]; 46 dis[behind.x][behind.y]=dis[front.x][front.y]+1;//距离加1,因为队列是 47 Q.push(behind); //先进先出所以是BFS 48 } 49 else if(vis[behind.x][behind.y]!=vis[front.x][front.y])//最短路径优先输出 50 { 51 printf("%d ",dis[front.x][front.y]+dis[behind.x][behind.y]+1);//相遇时少了一步 52 return; 53 } 54 } 55 } 56 } 57 } 58 int main() 59 { 60 int t; 61 scanf("%d",&t); 62 while(t--) 63 { 64 memset(vis,0,sizeof(vis)); 65 memset(dis,0,sizeof(dis)); 66 int x1,y1,x2,y2; 67 scanf("%d%d%d%d%d",&l,&x1,&y1,&x2,&y2); 68 dBFS(x1,y1,x2,y2); 69 70 } 71 return 0; 72 73 }
3.Red and Black
求定点连通块,直接DFS
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 using namespace std; 6 char map[30][30]; 7 bool vis[30][30]; 8 int w,h,step; 9 int orient[4][2]={1,0,0,1,-1,0,0,-1}; 10 struct position 11 { 12 int x,y; 13 }; 14 15 void DFS(int x,int y) 16 { 17 if(x<0||x>=h||y<0||y>=w||map[x][y]=='#') 18 return ; 19 if(vis[x][y]!=0)//发现不能用非,一个符号卡了我半小时 20 return; 21 vis[x][y]=1; 22 step=step+1;//计数器 23 for(int i=0;i<4;i++) 24 { 25 DFS(x+orient[i][0],y+orient[i][1]); 26 27 } 28 } 29 int main() 30 { 31 while(~scanf("%d%d",&w,&h)&&(w*h)!=0) 32 { 33 step=0; 34 position person; 35 memset(map,0,sizeof(map)); 36 memset(vis,0,sizeof(vis)); 37 for(int i=0;i<h;i++) 38 { 39 getchar();//吸掉每次换行的回车,包括第一次输入w,h 40 for(int j=0;j<w;j++) 41 { 42 scanf("%c",&map[i][j]); 43 if(map[i][j]=='@') 44 { 45 person.y=i,person.x=j;//记录人的位置 46 //vis[i][j]=1; 47 } 48 } 49 } 50 DFS(person.y,person.x); 51 printf("%d ",step); 52 53 } 54 return 0; 55 }