poj3126 Prime Path 搜索BFS
题目:
每次每一位上只能该位变一个数字,并且组成一个新的素数,
问最少能用多少次变成第二个给出的素数
分析:
既然归类到了BFS,可以用BFS来做,可先生成一个素数判断表,
加快判断,然后枚举每一位上的数,给以往的BFS一样,只不过
每次要计算0到9而已(注意:千位上不能为0,个位上是偶数的话
就不用考虑了)
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
int m,n,ans;
int a[6];
bool isprime[10000],use[10000];
void make_prime()
{//生成判断10000以内的素数数组,为真时不是素数
memset(isprime,false,sizeof(isprime));
for(int i=3;i<=9999;i+=2)
if(!isprime[i])
for(int j=i+i;j<10000;j+=i)
isprime[j] = true;
}
void bfs()
{
int x;
queue<int> p;//记录当前的次数
queue<int> q;//记录当前的四位数
p.push(0);
q.push(m);
while(!q.empty())
{
int t = q.front();
ans = p.front();
q.pop();
p.pop();
if(t==n) //当成功时结束
return;
for(int i=1;i<=4;i++)//分别记录四位数上的每一位数
{
a[i] = t;
t/=10;
}
for(int j=1;j<=9;j++)
{ //千位的在变,千位上不能为0
x = j*1000+a[3]*100+a[2]*10+a[1];//当前的数
if(!isprime[x]&&!use[x])
{ //是素数并且没用过时
q.push(x);
p.push(ans+1);
use[x] = true;//表示已经试过了
}
}
for(int j=0;j<=9;j++)
{ //百位的在变
x = a[4]*1000+j*100+a[2]*10+a[1];
if(!isprime[x]&&!use[x])
{
q.push(x);
p.push(ans+1);
use[x] = true;
}
}
for(int j=0;j<=9;j++)
{ //十位的在变
x = a[4]*1000+a[3]*100+j*10+a[1];
if(!isprime[x]&&!use[x])
{
q.push(x);
p.push(ans+1);
use[x] = true;
}
}
for(int j=1;j<=9;j+=2)
{ //个位的在变,直接从1开始,每次增加2
x = a[4]*1000+a[3]*100+a[2]*10+j;
if(!isprime[x]&&!use[x])
{
q.push(x);
p.push(ans+1);
use[x] = true;
}
}
}
}
int main()
{
freopen("sum.in","r",stdin);
freopen("sum.out","w",stdout);
make_prime();
int t;
cin>>t;
while(t--)
{
memset(use,false,sizeof(use));
ans = 0;
cin>>m>>n;
bfs();
cout<<ans<<endl;
}
return 0;
}