第八天 bfs
题
1
迷宫最短路问题
————————————
题解
#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
struct node{
int x,y,d;
node(int xx,int yy,int dd){
x = xx;
y = yy;
d = dd;
}
};
int dir[4][2] = {{-1,0},{0,-1},{1,0},{0,1}};
char mp[10][10];
int n,m;
bool vis[10][10];
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(tx>=0&&tx<n&&ty>=0&&ty<m&&!vis[tx][ty]&&mp[tx][ty] != '*'){
// cout <<tx<< " "<<ty;
if(mp[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++){
cin >>mp[i];
}
int x,y;
for(int i = 0;i<n;i++){
for(int j = 0;j<m;j++){
// cout <<mp[i][j];
if(mp[i][j] == 'S'){
x = i;
y = j;
}
}
}
// cout <<x<<" "<<y;
cout <<bfs(x,y)<<endl;
return 0;
}
2
在一个长度为 n 的坐标轴上,蒜头君想从 A 点 移动到 B 点。他的移动规则如下:
向前一步,坐标增加 1。
向后一步,坐标减少 1。
跳跃一步,使得坐标乘 2。
蒜头君不能移动到坐标小于 0 或大于 n 的位置。蒜头想知道从 A 点移动到 B 点的最少步数是多少,你能帮他计算出来么?
输入格式
第一行输入三个整数 n,A,B,分别代表坐标轴长度,起始点坐标,终点坐标。(50000≤A,B≤n≤5000)
输出格式
输出一个整数占一行,代表蒜头要走的最少步数。
样例输入
10 2 7
样例输出
3
——————————————
题解
#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
int n,A,B,now,step;
queue<pair<int, int> > q;
bool vis[50];
int main(){
cin >>n>>A>>B;
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;
}
3
密码锁
现在一个紧急的任务是打开一个密码锁。密码由四位数字组成,每个数字从 到 进行编号。每次
可以对任何一位数字加 或减 。当将 9 加 时,数字将变为 1 ,当 1 减 的时,数字将变
为 9 。你也可以交换相邻数字,每一个行动记做一步。现在你的任务是使用最小的步骤来打开锁。
注意:最左边的数字不与最右边的数字相邻。
输入格式
第一行输入四位数字,表示密码锁的初始状态。
第二行输入四位数字,表示开锁的密码。
输出格式
输出一个整数,表示最小步骤。
样例输入
1234
2144
样例输出
2
————————————————
题解
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
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();
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(){
char s1[10],s2[10];
scanf("%s",s1);
scanf("%s",s2);
// cout <<s1<<s2;
for(int i = 0;i<4;i++){
first.num[i] = s1[i]-'0';
last.num[i] = s2[i]-'0';
// cout <<first.num[i]<<" "<<last.num[i]<<endl;
}
bfs();
return 0;
}