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);
}
}
}
本文来自博客园,作者:CinqueOrigin,转载请注明原文链接:https://www.cnblogs.com/CinqueOrigin/p/15782179.html