10.广度优先搜索 BFS![在这里插入图片描述](https://img-blog.csdnimg.cn/2020031310184679.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0EyMzM2NjY=,size_16,color_FFFFFF,t_70)
1.队列queue
#include<iostream>
#include<queue>
using namespace std;
int main(){
queue<int> q;
q.push(1);
q.push(2);
q.push(3);
cout<<q.front()<<endl;//1
q.pop();
if(!q.empty()){
cout<<q.front()<<endl;//2
}
//队列没有clear()方法,可以这样清空
while(!q.empty() ){
q.pop();
}
return 0;
}
2.书院主持人
北大附中书院有m个同学,他们每次都很民主地决策很多事情。按罗伯特议事规则,需要一个主持人。同学们民主意识强,积极性高,都想做主持人,当然主持人只有一人。为了选出主持人,他们想到了一个办法并认为很民主。方法是:大家围成一圈,从1到m为每个同学编号。然后从1开始报数, 数到n的出局。剩下的同学从下位开始再从1开始报数。最后剩下来的就是主持人了。现在已经把同学从1到m编号,并约定报数为n的出局,请编程计算一下,哪个编号的同学将会成为主持人。
#include<iostream>
#include<queue>
using namespace std;
int main() {
int n,m;
cin>>n>>m;
queue<int> q;
for(int i=1;i<=n;i++){
q.push(i);
}
int cur=1;
while(q.size()>1){
int x=q.front();
q.pop();
if(cur!=m){
q.push(x);
cur++;
} else{
cur=1;
}
}
cout<<q.front()<<endl;
}
3.迷宫问题
对于DFS要枚举所有的可能性,如果地图过大,那么效率很低
对于BFS是分层搜索,因此第一次搜索到终点时,当前搜素的层数就是最短路径的长度
#include<iostream>
#include<queue>
using namespace std;
int n,m;
char maze[105][105];
bool vis[105][105];
int dir[4][2]={{-1,0},{0,-1},{1,0},{0,1}};//方向
bool in(int x,int y){//范围
return x>=0 && x<n && y>=0 && y<m;
}
//节点
struct node{
int x,y,d;
node(int xx,int yy,int dd){
x=xx;
y=yy;
d=dd;
}
};
int bfs(int sx,int sy){
queue<node> q;
q.push(node(sx,sy,0));
vis[sx][sy]=true;
while(!q.empty()){
node now=q.front();
q.pop();
for(int i=0;i<4;i++){
int tx=now.x+dir[i][0];
int ty=now.y+dir[i][1];
if(in(tx,ty) && maze[tx][ty]!='*' && !vis[tx][ty]){
if(maze[tx][ty]=='T'){
return now.d +1;
}else{
vis[tx][ty]=true;
q.push(node(tx,ty,now.d+1));
}
}
}
}
return -1;
}
int main(){
cin>>n>>m;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
cin>>maze[i][j];
}
}
int x,y;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(maze[i][j]=='S'){
x=i;
y=j;
}
}
}
cout<<bfs(x,y)<<endl;
return 0;
}
/*
样例输入:
5 6
....S*
.**...
.*..*.
*..**.
.T....
样例输出:
7
*/
4.一维坐标的移动
/*在长度为【0,n】的一维坐标中,输入A,B的地址,问能否从A到B。
移动方式:向前一步(坐标+1),向后一步(坐标-1),跳(坐标*2)*/
#include<iostream>
#include<queue>
#include<utility>
using namespace std;
bool vis[100];
int main() {
int n,A,B,now,step;
cin>>n>>A>>B;
queue< pair<int,int> >q;
q.push(make_pair(A,0));
vis[A]=true;
while(!q.empty()) {
now=q.front().first;
step=q.front().second;
q.pop();
if(now==B){
cout<<step<<endl;
break;
}
if(now+1<=n && !vis[now+1]) {
q.push(make_pair(now+1,step+1));
vis[now+1]=true;
}
if(now-1>=0 && !vis[now-1]) {
q.push(make_pair(now-1,step+1));
vis[now-1]=true;
}
if(now*2<=n && !vis[now*2]) {
q.push(make_pair(now*2,step+1));
vis[now*2]=true;
}
}
return 0;
}
/*
样例输入:
10 2 7
样例输出
3
*/
5.密码锁
#include<iostream>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
struct node {
int num[4],step;
} first,last;
int vis[11][11][11][11];
void bfs() {
int i;
node a,next;
queue<node> q;
a=first;
a.step=0;
q.push(a);
memset(vis,0,sizeof(vis));
vis[a.num[0]][a.num[1]][a.num[2]][a.num[3]]=1;
while(!q.empty()) {
a=q.front();
q.pop();
//bfs出口
if(a.num[0]==last.num[0] && a.num[1]==last.num[1]
&&a.num[2]==last.num[2] &&a.num[3]==last.num[3] ) {
cout<<a.step<<endl;
return;
}
for(int i=0; i<4; i++) { //++1
next=a;
next.num[i]++;
if(next.num[i]==10) {
next.num[i]=1;
}
if(!vis[next.num[0]][next.num[1]][next.num[2]][next.num[3]]) {
vis[next.num[0]][next.num[1]][next.num[2]][next.num[3]]=1;
next.step++;
q.push(next);
}
}
for(int i=0; i<4; i++) { //--1
next=a;
next.num[i]--;
if(next.num[i]==0) {
next.num[i]=9;
}
if(!vis[next.num[0]][next.num[1]][next.num[2]][next.num[3]]) {
vis[next.num[0]][next.num[1]][next.num[2]][next.num[3]]=1;
next.step++;
q.push(next);
}
}
for(int i=0; i<3; i++) {//交换
next=a;
next.num[i]=a.num[i+1];
next.num[i+1]=a.num[i];
if(!vis[next.num[0]][next.num[1]][next.num[2]][next.num[3]]) {
vis[next.num[0]][next.num[1]][next.num[2]][next.num[3]]=1;
next.step++;
q.push(next);
}
}
}
}
int main() {
int i,j,k;
char s1[10],s2[10];
cin>>s1>>s2;
for(int i=0; i<4; i++) {
first.num[i]=s1[i]-'0';
last.num[i]=s2[i]-'0';
}
bfs();
return 0;
}
/*
样例输入:
1234
2144
样例输出:
2
*/
6.三阶平面魔方
#include<iostream>
#include<map>
#include<queue>
#include<cstdio>
using namespace std;
struct node{
int a[3][3];
bool operator < (const node &x) const{
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
if(a[i][j]<x.a[i][j]){
return 1;
}
}
}
return 0;
}
bool operator == (const node &x) const{
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
if(a[i][j]!=x.a[i][j]){
return 0;
}
}
}
return 1;
}
void print(){
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
cout<<a[i][j]<<" ";
}
cout<<endl;
}
}
int tonum(){
int res=0;
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
res=res*10+a[i][j];
}
}
return res;
}
} init;
node rotate(node a,int s,int d){
node res=a;
if(d==-1){ //right move
int tmp=res.a[s][2];
res.a[s][2]=res.a[s][1];
res.a[s][1]=res.a[s][0];
res.a[s][0]=tmp;
}else if(d==1){ // left move
int tmp=res.a[s][0];
res.a[s][0]=res.a[s][1];
res.a[s][1]=res.a[s][2];
res.a[s][2]=tmp;
}else if(d==-2){ //up move
int tmp=res.a[0][s];
res.a[0][s]=res.a[1][s];
res.a[1][s]=res.a[2][s];
res.a[2][s]=tmp;
} else if(d==2){ // down move
int tmp=res.a[2][s];
res.a[2][s]=res.a[1][s];
res.a[1][s]=res.a[0][s];
res.a[0][s]=tmp;
}
return res;
}
int bfs(node st){
queue<node> q;
map<int,int> d;
q.push(st);
d[st.tonum()]=0;
while(!q.empty()){
node x=q.front();
q.pop();
int tt=x.tonum();
if(x==init){
return d[x.tonum()];
}
node tmp;
for(int i=0;i<3;i++){
tmp=rotate(x,i,-1);
if(!d.count(tmp.tonum())){
d[tmp.tonum()]=d[tt]+1;
q.push(tmp);
}
tmp=rotate(x,i,1);
if(!d.count(tmp.tonum())){
d[tmp.tonum()]=d[tt]+1;
q.push(tmp);
}
}
for(int i=0;i<3;i++){
tmp=rotate(x,i,-2);
if(!d.count(tmp.tonum())){
d[tmp.tonum()]=d[tt]+1;
q.push(tmp);
}
tmp=rotate(x,i,2);
if(!d.count(tmp.tonum())){
d[tmp.tonum()]=d[tt]+1;
q.push(tmp);
}
}
}
return -1;
}
int main(){
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
init.a[i][j]=i*3+j+1;
}
}
node t;
for(int i=0;i<3;i++){
int n;
cin>>n;
t.a[i][2]=n%10;
n/=10;
t.a[i][1]=n%10;
n/=10;
t.a[i][0]=n;
}
int ans=bfs(t);
cout<<ans<<endl;
return 0;
}
/*
样例输入:
412
756
389
样例输出:
2
*/
7.吃糖的时间![在这里插入图片描述](https://img-blog.csdnimg.cn/20200313102046154.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0EyMzM2NjY=,size_16,color_FFFFFF,t_70)
#include<iostream>
#include<queue>
#include<vector>
#include<cstdlib>
using namespace std;
typedef struct{
int v;
int step;
}node;
int maxn;
queue<node> q;
vector<int> g[100010];
bool vis[100010];
void bfs(){
int i;
node p,t;
while(!q.empty()){
p=q.front();
q.pop();
for(int i=0;i<g[p.v].size();i++){
t.v=g[p.v][i];
t.step=p.step+1;
if(!vis[t.v]){
q.push(t);
vis[t.v]=1;
if(t.step>maxn){
maxn=t.step;
}
}
}
}
}
int main(){
node t;
int n,p,c,m,a,b,i;
cin>>n>>p>>c;
cin>>m;
for(int i=0;i<p;i++){
cin>>a>>b;
g[a].push_back(b);
g[b].push_back(a);
}
t.v=c;
t.step=1;
vis[t.v]=1;
q.push(t);
bfs();
cout<<maxn+m<<endl;
return 0;
}
/*
样例输入:
4 3 1
2
1 2
2 3
1 4
样例输出:
5
*/