题意:
给你两个素数,n,m;
问你能够最少几步把n变成m;
变的规则: 每次能够变一位数字,要求变完,仍然是素数;
n,m都是4位数
思路:
BFS,先用素数筛把10000都筛出来,然后用BFS,对个十百千位的数字去枚举(千位不能是0)
16ms
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
int n, m;
int sx[10000];
int vis[10000];
struct node
{
int s;
int step;
} now,next;
void bfs()
{
memset(vis,0,sizeof(vis));
queue<node> que;
now.s = n;
now.step = 0;
que.push(now);
int i;
vis[n] = 1;
while(!que.empty())
{
now = que.front();
que.pop();
int s = now.s;
int step = now.step;
if(s == m)
{
printf("%d\n",step);
return;
}
int s1, s2, s3, s4;
s1 = s/1000;
s2 = (s/100)%10;
s4 = s%10;
s3 = (s%100-s4)/10;
int sum;
for(i = 0; i <10; i++)
{
sum = s1*1000+s2*100+s3*10+i;
if(!sx[sum]&&!vis[sum])
{
next.s = sum;
next.step = step+1;
vis[sum] = 1;
que.push(next);
}
sum = s1*1000+s2*100+i*10+s4;
if(!sx[sum]&&!vis[sum])
{
next.s = sum;
next.step = step+1;
vis[sum] = 1;
que.push(next);
}
sum = s1*1000+i*100+s3*10+s4;
if(!sx[sum]&&!vis[sum])
{
next.s = sum;
next.step = step+1;
vis[sum] = 1;
que.push(next);
}
if(i >0)
{
sum = i*1000+s2*100+s3*10+s4;
if(!sx[sum]&&!vis[sum])
{
next.s = sum;
next.step = step+1;
vis[sum] = 1;
que.push(next);
}
}
}
}
}
int main()
{
int t;
scanf("%d",&t);
memset(sx,0,sizeof(sx));
for(int i = 2; i < 10000/2; i++)
for(int j=i*i; j < 10000; j+=i)
sx[j] = 1;
while(t--)
{
scanf("%d%d",&n,&m);
bfs();
}
return 0;
}