题目来源:poj 3126
大致题意:
给定两个四位素数a b,要求把a变换到b
变换的过程要保证 每次变换出来的数都是一个 四位素数,而且当前这步的变换所得的素数 与 前一步得到的素数 只能有一个位不同,而且每步得到的素数都不能重复。
求从a到b最少需要的变换次数。无法变换则输出Impossible。
#include <iostream>
#include <queue>
#include <algorithm>
#include <string>
using namespace std;
struct node
{
string c; //表示数字
int step; //表示步数
}start, stop;
const int maxn = 10000; //表长
int prime[maxn]; //prime数组存放所有素数
int pNum; //素数个数
bool p[maxn] = {false}; //p[i]==true表示i被筛掉,则i不是素数
bool vis[maxn] = {false};
void Find_Prime()
{
for (int i = 2; i < maxn; i++)
{
if (p[i] == false)
{
prime[pNum++] = i;
for (int j = i + i; j < maxn; j = j + i)
{
p[j] = true;
}
}
}
}
void BFS()
{
queue<node> Q;
start.step = 0;
int a = (start.c[0]-'0')*1000+(start.c[1]-'0')*100+(start.c[2]-'0')*10+start.c[3]-'0';
vis[a] = true;
Q.push(start);
if (start.c == stop.c)
{
cout << '0' << endl;
return;
}
while (!Q.empty())
{
node top = Q.front();
Q.pop();
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 4; j++)
{
if (i == 0 && j == 0) //第一个位置上不可以是0
{
continue;
}
string temp = top.c;
temp[j] = i + '0';
int num = (temp[0] - '0') * 1000 + (temp[1] - '0') * 100 + (temp[2] - '0') * 10 + temp[3] - '0';
if (!p[num] && vis[num] == false)
{
vis[num] = true;
node new_one;
new_one.c = temp;
new_one.step = top.step + 1;
Q.push(new_one);
if (temp == stop.c)
{
cout << top.step + 1 << endl;
return;
}
}
}
}
}
}
int main()
{
Find_Prime();
int T;
cin >> T;
while (T--)
{
cin >> start.c;
cin >> stop.c;
BFS();
fill(vis, vis + maxn, false);
}
return 0;
}