第八天 bfs

第八天 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;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值