题意:
给你两个四位数的素数,问第一个经过几次变换能变换成第二个,并且变换变换过程中保证变换的数仍为素数!!
思路:
首先,筛四位数的素数,然后,利用创建一个队列,和数组,用来存放数字,如果出现过,将数组对应项置为1,然后进行广搜,符合条件的入队!!!!
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#define maxn 15
#define MAXN 10005
#define mod 1000000007
#define INF 0x3f3f3f3f
#define exp 1e-6
#define pi acos(-1.0)
using namespace std;
int isprime[MAXN]; //素数数组
int v[MAXN];
int flag=0;
struct node //结构体,存放调整的次数,数字,以及每位数
{
int w[5];
int s;
int num;
};
void go()
{
int i,j;
for(i=0;i<MAXN;i++)
isprime[i]=1;
isprime[0]=isprime[1]=0;
for (i=2;i<MAXN;i++)
{
if(isprime[i]==1)
{
for(int j=i+i;j<MAXN;j+=i)
{
isprime[j]=0;
}
}
}
}
int getdata(int a[],int b,int c) //生成新得到数
{
int ans=0;
for(int i=0;i<4;i++)
{
if(i==b)
ans=ans*10+c;
else
ans=ans*10+a[i];
}
return ans;
}
void work(int first,int second) //搜索
{
queue<node>ss;
int i,j,k,num1;
node start,endd;
memset(v,0,sizeof(v));
start.num=first;
start.s=0;
start.w[3]=first%10;
start.w[2]=(first/10)%10;
start.w[1]=(first/100)%10;
start.w[0]=(first/1000)%10;
ss.push(start);
while(!ss.empty())
{
endd=ss.front();
ss.pop();
if(endd.num==second)
{
cout<<endd.s<<endl;
flag=1; //定个flag,避免找不到的情形
break;
}
for(i=0;i<4;i++)
{
for(j=0;j<=9;j++)
{
if(i==0&&j==0)
continue;
if(endd.w[i]==j)
continue;
else
{
num1=getdata(endd.w,i,j);
if(isprime[num1]&&!v[num1]) //同时满足
{
v[num1]=1;
for(k=0;k<4;k++)
{
start.w[k]=endd.w[k];
}
start.num=num1;
start.w[i]=j;
start.s=endd.s+1;
ss.push(start); //入队
}
}
}
}
}
}
int main()
{
ios::sync_with_stdio(false);
int first,second;
int t;
go();
cin>>t;
while(t--)
{
flag=0;
cin>>first>>second;
work(first,second);
if(flag==0)
{
cout<<"Impossible"<<endl;
}
}
return 0;
}
多做题!!!!!!!!!!