poj3126 - bfs

题目主要意思是,给你两个4位数的质数A,B,要将A逐步换成B,每次只能换个十百千位中的其中一位,且换后的数也必须是质数,问你,至少要换多少步,才能把A换成B
例:1033换到8179      1033 >1733 >3733 >3739 >3779 >8779 >8179
输出   6
用数组P来判断数A是否是质数,数x是质数则P[x]为0,不是质数则P[x]为1。用visit判断该数是否被访问过,layer则表示该数的步数。
先将A放入队列,然后分别枚举个十百千位,生成新转换的数,如果它没访问过,且是质数,即将它放入队列,将其置为已经访问过,并将它的步数置为换成此数前的步数+1(layer[x]即表示A转换到x所需的步数),每次都将队首的数当成要被换掉的数,并将它弹出,队列中的数的步数都是队列前面的数的步数<=队列后面的数,以此能够保证最终,当得到新生成的数恰好等于B时,A到B的步数为最小。
#include <iostream>
#include <queue>
using namespace std;
int vis[10000];
int p[10000];
int layer[10000];
int a, b;
void prime() {
	p[0] = p[1] = 1;
	int i, j;
	for (i = 2; i < 10000; i++)
		if (p[i] == 0)
			for (j = i*i; j < 10000; j += i)
				p[j] = 1;
}
void init() {
	memset(vis, 0, sizeof(vis));
	memset(layer, 0, sizeof(layer));
}
int bfs() {
	queue<int > q;
	q.push(a);
	vis[a] = 1;
	layer[a] = 0; 
	while (!q.empty()) {
		int cur = q.front();
		int cur_copy = cur;
		q.pop();
		int t[4];
		int i;
		for (i = 3; i >= 0; i--) {
			t[i] = cur_copy % 10;
			cur_copy /= 10;
		}
		//枚举个位
		for (i = 0; i < 10; i++) {
			int next = i;
			next += t[0] * 1000 + t[1] * 100 + t[2] * 10;
			if (!p[next] && !vis[next]) {
				q.push(next);
				vis[next] = 1;
				layer[next] = layer[cur] + 1;
				if (next == b)
					return layer[next];
			}
		}
		//枚举s位
		for (i = 0; i < 10; i++) {
			int next = i*10;
			next += t[0] * 1000 + t[1] * 100 + t[3];
			if (!p[next] && !vis[next]) {
				q.push(next);
				vis[next] = 1;
				layer[next] = layer[cur] + 1;
				if (next == b)
					return layer[next];
			}
		}
		//枚举b位
		for (i = 0; i < 10; i++) {
			int next = i * 100;
			next += t[0] * 1000 + t[2] * 10 + t[3];
			if (!p[next] && !vis[next]) {
				q.push(next);
				vis[next] = 1;
				layer[next] = layer[cur] + 1;
				if (next == b)
					return layer[next];
			}
		}
		//枚举q位
		for (i = 1; i < 10; i++) {
			int next = i * 1000;
			next += t[1] * 100 +t[2] * 10 + t[3];
			if (!p[next] && !vis[next]) {
				q.push(next);
				vis[next] = 1;
				layer[next] = layer[cur] + 1;
				if (next == b)
					return layer[next];
			}
		}
	}
	return -1;
}
int main() {
	prime();
	int n;
	cin >> n;
	while (n--) {
		init();
		cin >> a >> b;
		if (a == b)
			cout << 0 << endl;
		else {
			int cnt = bfs();
			if (cnt == -1)
				cout << "Impossible" << endl;
			else
				cout << cnt << endl;
		}
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值