题意
给两个四位质数a,b, 每次只改变a的某一位,且得到的数a’必须是素数,问最少需要操作多少次才能使a变成b,不能则输出Impossible
分析
一个很纯的BFS的题目,先用素数筛打表,每次以O(1)的时间判断是否为素数。注意两个细节,千位不能是0,各位如果是偶数的话就没有必要搜索了。
代码
#include <iostream>
#include <cmath>
#include <queue>
#include <cstring>
using namespace std;
const int MAXN = 4000;
int v[10005], n;
int visit[10005];
void is_prime3()
{
for (int i = 2; i <= 9999; i++)
{
if (!v[i])
for (int j = i * i; j <= 9999; j += i)
v[j] = 1;
}
}
int main()
{
is_prime3();
int n,a,b;
cin >> n;
while (n--)
{
memset(visit, 0, sizeof(visit));
cin >> a >> b;
queue<pair<int,int>> que;
que.push(make_pair(a, 0));
visit[a] = 1;
while (que.size())
{
pair<int, int> now = que.front();
que.pop();
//如果找到了就退出
if (now.first == b) { cout << now.second << endl; break; }
int cu;
//搜索个位
cu = now.first / 10 * 10 + 1;
for (int i = 0; i < 5; i++)
{
if (!visit[cu] && !v[cu])
{
que.push(make_pair(cu, now.second + 1));
visit[cu] = 1;
}
cu += 2;
}
//搜索十位
cu = now.first / 100 * 100 + now.first % 10;
for (int i = 0; i <= 9; i++)
{
if (!visit[cu] && !v[cu])
{
que.push(make_pair(cu, now.second + 1));
visit[cu] = 1;
}
cu += 10;
}
//搜索百位
cu = now.first / 1000 * 1000 + now.first % 100;
for (int i = 0; i <= 9; i++)
{
if (!visit[cu] && !v[cu])
{
que.push(make_pair(cu, now.second + 1));
visit[cu] = 1;
}
cu += 100;
}
//搜索千位
cu = now.first % 1000 + 1000;
for (int i = 1; i <= 9; i++)
{
if (!visit[cu] && !v[cu])
{
que.push(make_pair(cu, now.second + 1));
visit[cu] = 1;
}
cu += 1000;
}
if (que.empty()) cout << "Impossible" << endl;
}
}
return 0;
}