<----my github

POJ 3126 Prime Path

问题的链接在这里
本题很明显是一个寻找最短路径的问题,直接利用BFS来解决即可。
本题中使用到了bitset这种结构,但是这种结构的访问速度相对于数组来说要慢一些,如果对时间有要求的话建议还是使用数组。bitset可以理解为文件系统中的位图。
本题的BFS思路是,首先明确1000-9999中哪个数是质数,然后把它用数组或上面提到的bitset标记;随后,开始探索节点并且使用队列/优先队列来保存节点。
探索节点:从个位到千位,每个位都尝试改其数值,如果修改数值后其值是质数而且该节点没有探索过,那么久加入队列。
取节点:直接出队一个元素即可。
终止条件:队列为空或者探索的节点就是要变成的门牌号。

详细的代码实现如下:

#include<iostream>
#include<math.h>
#include<bitset>
#include<queue>
using namespace std;
/*
	*由于1000-9999以内的素数有限,故可以考虑图的遍历方法
	* 由于要找的是最短路径,所以考虑使用BFS,用一个队列来解决这个问题
	* 每次生成节点的方法:变化四个数字中的一个,且不能与前面的数字重复
*/

//判断是否是质数
bool isPrime(int num) {
	int temp = sqrt((double)num);
	for (int i = 2; i <= temp; i++) {
		if (num % i == 0) return false;
	}
	return true;
}
//清空队列
void clear(queue<int>& q) {
	queue<int> empty;
	swap(empty, q);
}
int main() {
	int testNum;
	cin >> testNum;
	int begin, end;
	queue<int> queue;
	int expenditure[10000];
	bitset<10000> bitset;
	int temp;
	int i,j;
	bool flag = false;
	for (int i = 1001; i < 10000; i+=2)	//偶数不必考虑
	{
		if (isPrime(i))
			bitset.set(i);
	}
	while (testNum--) {
		cin >> begin >> end;
		if (begin == end) cout << 0 << endl;
		else if (!isPrime(begin) || !isPrime(end)) {
			cout << "Impossible" << endl;
		}
		else
		{	
			memset(expenditure, 0, sizeof(expenditure));
			queue.push(begin);
			expenditure[begin] = 1;
			while (!queue.empty()) 
			{
				temp = queue.front();
				queue.pop();
				if (temp == end) {
					cout << expenditure[temp] - 1 << endl; flag = true; ; break;
				}
				else {
					i = temp - temp % 10;
					//加入个位节点
					for (int k = 1; k < 10; k += 2) {
						j = i + k;
						if (j != temp && bitset.test(j) && !expenditure[j]) {
							queue.push(j);
							expenditure[j] = expenditure[temp]+1;
						}
					}
					//加入十位节点
					i = temp - temp % 100 + temp % 10;
					for (int k = 0; k < 10; k++) {
						j = i + k * 10;
						if (j != temp && bitset.test(j) && !expenditure[j]) {
							queue.push(j);
							expenditure[j] = expenditure[temp] + 1;
						}
					}
					i = temp-temp % 1000+temp%100;
					//百位节点
					for (int k = 0; k < 10; k++) {
						j = i + k * 100;
						if (j != temp && bitset.test(j) && !expenditure[j]) {
							queue.push(j);
							expenditure[j] = expenditure[temp] + 1;
						}
					}
					i = temp % 1000;
					//qianwei
					for (int k = 1; k < 10; k++) {
						j = i + k * 1000;
						if (j != temp && bitset.test(j) && !expenditure[j]) {
							queue.push(j);
							expenditure[j] = expenditure[temp] + 1;
						}
					}
				}
			}
			if(!flag)			cout << "Impossible" << endl;
			clear(queue);
		}
	}
}
posted @ 2022-01-10 19:10  CinqueOrigin  阅读(42)  评论(0)    收藏  举报