分析: 简单的BFS。一次只能变一个位,最短路径,自然就想到了BFS。首先进行预处理:构建一个1000到9999的素数表,然后构建一个无向图(比较推荐使用vector的形式)。对于每次输入,使用BFS即可。
此题文字描述较长,且需要一些预处理,所以看上去“有点难”,但只要仔细分析,不难求解。
代码如下:
#include <iostream>
#include <cmath>
#include <queue>
#include <vector>
#include <memory.h>
#define MAX 10003
using namespace std;
int start,target;
bool prime[MAX];
int mark[MAX];
vector<int> grap[MAX];
struct node
{
int val,dis;
node(int x = 0,int y = 0) : val(x) , dis(y) { }
};
queue<node> q;
void bfs()
{
memset(mark,0,sizeof(mark));
while(!q.empty()) q.pop();
node tem(start,0);
q.push(tem);
while(!q.empty())
{
tem = q.front();
q.pop();
for (int i = 0;i < grap[tem.val].size();i ++)
{
int k = grap[tem.val][i];
if (k == target)
{
cout << tem.dis + 1 << endl;
return;
}
if (mark[k]) continue;
mark[k] = 1;
q.push(node(k,tem.dis + 1));
}
}
}
int main()
{
// 建立素数表 (这是一个小技巧,不用写判断质数函数)
for (int i = 1000;i < MAX;i ++)
prime[i] = true;
for (int i = 1000;i < MAX;i += 2)
prime[i] = false;
for (int i = 3;i <= sqrt(MAX) + 1;i += 2)
{
for (int j = i;j < MAX / i;j += 2)
prime[i * j] = false;
}
// 建立无向图
for (int i = 1000;i <= 9999;i ++)
{
if (!prime[i]) continue;
int tem = i,num[4];
num[0] = tem / 1000; tem = tem % 1000;
num[1] = tem / 100; tem = tem % 100;
num[2] = tem / 10; num[3] = tem % 10;
for (int j = 1;j <= 9;j ++)
{
tem = j * 1000 + num[1] * 100 + num[2] * 10 + num[3];
if (tem != i && prime[tem])
grap[i].push_back(tem);
}
for (int j = 0;j <= 9;j ++)
{
tem = num[0] * 1000 + j * 100 + num[2] * 10 + num[3];
if (tem != i && prime[tem])
grap[i].push_back(tem);
}
for (int j = 0;j <= 9;j ++)
{
tem = num[0] * 1000 + num[1] * 100 + j * 10 + num[3];
if (tem != i && prime[tem])
grap[i].push_back(tem);
}
for (int j = 0;j <= 9;j ++)
{
tem = num[0] * 1000 + num[1] * 100 + num[2] * 10 + j;
if (tem != i && prime[tem])
grap[i].push_back(tem);
}
}
int cases;
cin >> cases;
while(cases --)
{
cin >> start >> target;
if (start == target) cout << 0 << endl;
else bfs();
}
}