POJ 3126

素数路径。给两个素数,9999以下,每次只能变一个数位,求最小变化次数。

先构图,再BFS,和3278思路一样

 

这类题,还是比个熟练程度。

 

#include <iostream> #define F(i,a,b) for (int i=a;i<=b;i++) using namespace std; bool p[10000]; void getP() { memset(p, 0, sizeof(p) ); F(i,2,10000) { if (!p[i]) { for (int j=i+i;j<=10000;j+=i) p[j]=true; } } } bool mk[10002]; int lst[10002][42], Q[10002], s, e, steps[10002]; void bfs() { memset(mk, 0, sizeof(mk) ); memset(steps, 0 ,sizeof(steps) ); Q[0]=s; int now=0,last=1; mk[s]=true; while (now<last && Q[now]!=e) { int v=Q[now]; F(i,1, lst[v][0] ) if (!mk[ lst[v][i] ]) { Q[last++]=lst[v][i]; steps[ lst[v][i] ]=steps[v]+1; mk[ lst[v][i] ]=true; } now++; } } int main() { int t, T; // freopen ("in.txt", "r" ,stdin); getP(); F(i,1000,9999) { // thousand t=i%1000; for (int j=0;j<=9000;j+=1000) if (j+t!=i && !p[ j+t ] ) lst[i][ ++lst[i][0] ]=j+t; //hundred t=i-(i/100)%10*100; for (int j=0;j<=900;j+=100) if (j+t!=i && !p[j+t] ) lst[i][ ++lst[i][0] ]=j+t; //ten t=i-(i/10)%10*10; for (int j=0;j<=90;j+=10) if (j+t!=i && !p[j+t] ) lst[i][ ++lst[i][0] ]=j+t; //single t=i-i%10; for (int j=0;j<=9;j++) if (j+t!=i && !p[j+t]) lst[i][ ++lst[i][0] ]=j+t; } cin >> T; F(i,1,T) { cin >> s >> e; bfs(); cout << steps[e] << endl; } return 0; }

你可能感兴趣的:(POJ 3126)