POJ3126Prime Path
题意&思路:
给两个数,又第一个数改变到第二个数的奇数路径最少是多少。每次只能改变一位,且不含前导0,每次改变后的数都要为奇数。
先把素数筛出来,然后按位子改变bfs即可,第一位不能为0以及最后一位一定不可能是偶数。
代码:
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
#include<string.h>
#include<ctype.h>
#include<queue>
#include<set>
#include<stack>
#include<cmath>
const int N=1e5+10;
const int mod=1e7+9;
const int maxn=0x3f3f3f3f;
const int minn=0xc0c0c0c0;
const int inf=99999999;
using namespace std;
int prime[N]={0},p[N]={0},pos=0,vis[N],ans;
int a,b;
void find()
{
int i,j;
for(i=2;i<=N;i++)
{
if(prime[i]==0)
p[++pos]=i;
for(j=1;j<=pos;j++)
{
if(i*p[j]>N)
break;
prime[i*p[j]]=1;
if(i%p[j]==0)
break;
}
}
}
struct num
{
int k[4],time;
}be;
int f(num a)
{
int i,res=0;
for(i=0;i<4;i++)
res=res*10+a.k[i];
return res;
}
int bfs()
{
int i,j;
num pre,temp;
vis[f(be)]=1;
queue<num> q;
q.push(be);
while(!q.empty())
{
pre=q.front();
q.pop();
if(f(pre)==b)
return pre.time;
for(i=0;i<4;i++)
{
for(j=0;j<=9;j++)
{
temp=pre;
temp.k[i]=j;
if((i==0 && j==0) || (i==3 && j&1==0) || vis[f(temp)] || prime[f(temp)])
continue;
temp.time=pre.time+1;
vis[f(temp)]=1;
q.push(temp);
}
}
}
return -1;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int n,l;
find();
cin>>n;
while(n--)
{
cin>>a>>b;
l=3;
while(a)
{
be.k[l--]=a%10;
a/=10;
}
memset(vis,0,sizeof(vis));
ans=bfs();
if(ans==-1)
cout<<"Impossible"<<endl;
else
cout<<ans<<endl;
}
return 0;
}