题目链接:POJ 3126 Prime Path
题意:给出两个四位素数,要求从第一个素数变到第二个素数。
变换规则:每次只能改变四位数中的一个数,并且要求变换后的数依旧是素数。
求最少的变换次数。
思路:先把1000-10000之间的数判断好是不是素数,之后直接用。
然后BFS搜索,每次变换一个数,变换后的数要求是素数,保证是四位数则不能有前导0.
代码:
//Must so
#include<iostream>
#include<algorithm>
#include<string>
#include<sstream>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<cstdio>
#include<cmath>
#define mem(a,x) memset(a,x,sizeof(a))
#define sqrt(n) sqrt((double)n)
#define pow(a,b) pow((double)a,(int)b)
#define inf 1<<29
#define NN 1000006
using namespace std;
const double PI = acos(-1.0);
typedef long long LL;
struct Node
{
int x;
int step;
};
bool prime[10005];
bool vis[10005];
int d[10] = {0,1,2,3,4,5,6,7,8,9};
int a[4];
bool isprime(int x)
{
for (int i = 2;i <= sqrt(x);i++)
{
if (x%i == 0) return 0;
}
return 1;
}
void init()
{
for (int i = 1000;i <= 9999;i++)
{
if (isprime(i)) prime[i] = 1;
}
}
void fool(int x)
{
for (int i = 3;i >= 0;i--)
{
a[i] = x%10;
x/=10;
}
}
inline int boor()
{
return a[0]*1000+a[1]*100+a[2]*10+a[3];
}
void bfs(int s,int t)
{
queue<Node>q;
for (int i = 1000;i <= 9999;i++)
{
vis[i] = 0;
}
Node h;
h.x = s;
h.step = 0;
vis[s] = 1;
q.push(h);
while (!q.empty())
{
h = q.front();
if (h.x == t)
{
cout<<h.step<<endl;
return;
}
q.pop();
//vis[h.x] = 0;
for (int i = 0;i < 4;i++)
{
fool(h.x);
for (int j = 0;j < 10;j++)
{
if (a[i] == d[j]) continue;//数字没有改变
if (i == 0&&j == 0) continue;//不能有前导0
a[i] = d[j];//改变一个数
int now = boor();//获取新的数字
if (prime[now]&&vis[now] == 0)//是素数并且没有访问过
{
Node nx;
nx.x = now;
nx.step = h.step+1;
q.push(nx);
vis[now] = 1;//标记为访问过
}
}
}
}
//走完并无解
cout<<"Impossible"<<endl;
}
int main()
{
init();
int T;
cin>>T;
while (T--)
{
int s,t;
cin>>s>>t;
bfs(s,t);
}
return 0;
}