2017年蓝桥杯省赛填空题- 跳蚱蜢

题目

题目链接

题解

BFS(+STL)


最少次数,每次跳跃对次数的贡献都是1,完全可以抽象理解为最短路,所以采用BFS可以直接算出最短长度。


状态转移存在四种,以题中给的状态为例,可以选择2跳到空处、1跳到空处、7跳到空处或8跳到空处。标记一下遇到过的状态,不要再加入队列中了。

代码

#include<bits/stdc++.h>
#define PIV pair <int, vector <int> >
using namespace std;

int ans = 0;
vector <int> target = {0, 8, 7, 6, 5, 4, 3, 2, 1}; // 目标状态 
map <vector <int>, int> st; // 标记 

vector <int> exchage (vector <int> v, int x, int y) {
	swap (v[x], v[y]);
	return v;
}

void bfs () {
	queue <PIV> q; // I表示0的位置,V表示状态 
	vector <int> s;
	s = {0, 1, 2, 3, 4, 5, 6, 7, 8};
	q.push ({0, s});
	st[s] = 1;
	
	while (q.size()) {
		int k = q.size ();
		ans ++;
		for (int i = 0;i < k;i ++) {
			PIV t = q.front();
			q.pop ();
			int pos_0 = t.first, ex_pos; // pos_0 : 0的位置,ex_pos : 要跳跃的蚱蜢的位置 
			vector <int> state = t.second;
			vector <int> new_state; // 跳后状态 
			
			ex_pos = (pos_0 + 1) % 9; // 有四种跳跃方式,从左上跳到空处两种,右侧两种,总共四种 
			new_state = exchage (state, pos_0, ex_pos); // 跳跃后的状态 
			if (new_state == target) return ; // 目标 
			if (st.count(new_state) == 0)  { // 没遍历过该状态 
				q.push ({ex_pos, new_state}); // 扩展 
				st[new_state] = 1; // 标记 
			}
			
			ex_pos = (pos_0 + 2) % 9;
			new_state = exchage (state, pos_0, ex_pos);
			if (new_state == target) return ;
			if (st.count(new_state) == 0)  {
				q.push ({ex_pos, new_state});
				st[new_state] = 1;
			}
			
			ex_pos = (pos_0 - 1 + 9) % 9;
			new_state = exchage (state, pos_0, ex_pos);
			if (new_state == target) return ;
			if (st.count(new_state) == 0)  {
				q.push ({ex_pos, new_state});
				st[new_state] = 1;
			}
			
			ex_pos = (pos_0 - 2 + 9) % 9;
			new_state = exchage (state, pos_0, ex_pos);
			if (new_state == target) return ;
			if (st.count(new_state) == 0)  {
				q.push ({ex_pos, new_state});
				st[new_state] = 1;
			}
		}
	}
}


int main()
{
	bfs ();
	
	cout << ans << endl; 
	 
	return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不牌不改

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值