題目描述其實就是篇小故事,不多解釋直接說明題意。題意要求給兩個4位的素數,求出將前一個素數轉化爲後一個素數需要的步數。一次只能改變一位數字,且保證每次改變得到的數都是素數
思路:用BFS暴搜,每次改變一位數如果是素數就進入隊列,但是暴搜的前提要把1w以內的素數篩出來。爲了方便對每一位上的數的操作,本人用的字符串來儲存4位數字。
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <queue>
#define INF 0x3f3f3f3f
#define mod 1000000007
using namespace std;
bool prime[10001];
bool flag[10001];
struct node
{
char str[6];
int step;
}turn;
void getprime()
{
for (int i=2;i*i<=10000;i++)
{
if(!prime[i])
for (int j=i;j*i<=10000;j++)
{
prime[i*j]=1;
}
}
}
int BFS(char a[],char b[])
{
if(strcmp(a,b)==0) return 0;
queue<node>Q;
int i,j,num,step;
char x;
strcpy(turn.str,a);
turn.step=0;
num=(turn.str[0]-'0')*1000+(turn.str[1]-'0')*100+(turn.str[2]-'0')*10+turn.str[3]-'0';
flag[num]=1;
Q.push(turn);
while(!Q.empty())
{
turn=Q.front();
step=turn.step;
Q.pop();
for (i=0;i<=3;i++)
{
x=turn.str[i];
i==0 ? j='1' : j='0';
for(;j<='9';j++)
{
if(j==x) continue;
turn.str[i]=j;
turn.step=step+1;
if(strcmp(turn.str,b)==0) return turn.step;
num=(turn.str[0]-'0')*1000+(turn.str[1]-'0')*100+(turn.str[2]-'0')*10+turn.str[3]-'0';
if(!prime[num]&&!flag[num])
{
flag[num]=1;
Q.push(turn);
}
}
turn.str[i]=x;
}
}
return -1;
}
int main()
{
getprime();
int t,step;
char x[6],y[6];
scanf("%d",&t);
while(t--)
{
memset(flag,0,sizeof(flag));
scanf("%s%s",x,y);
step=BFS(x,y);
printf("%d\n",step);
}
return 0;
}