一、题目
http://poj.org/problem?id=3126
二、分析
该题主要是要让我们找到一个$4$位素数到另一个$4$位素数的最少的变换次数,且要求保证每一次变换都满足
1.下一个数必须是4位。
2.下一个数必须是素数。
知道满足这两个条件后,然后结合$BFS$即可求出解。
这里有个处理4位数变换的技巧就是通过一个式子完成。
$next = P\%T[i]+P/T[i+1]*T[i+1]+j*T[i]$
这里的$T$数组为${1, 10, 100, 1000, 10000}$。具体的证明可以自己多画几项就出来了。
三、AC代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <cmath> using namespace std; const int MAXN = 1e5; bool isPrime[MAXN]; bool visit[MAXN]; const int T[] = {1, 10, 100, 1000, 10000}; int Start, End; struct Node { int value; int step; }; void getPrime() { memset(isPrime, 1, sizeof(isPrime)); isPrime[0] = isPrime[1] = 0; for(int i = 2; i < MAXN; i++) { if(isPrime[i]) { for(int j = i*2; j < MAXN; j+=i) { isPrime[j] = 0; } } } } int BFS() { memset(visit, 0, sizeof(visit)); Node t; t.value = Start; visit[t.value] = 1; t.step = 0; if(t.value == End) return t.step; queue<Node> Q; Q.push(t); while( !Q.empty() ) { Node p = Q.front(); Q.pop(); t.step = p.step+1; for(int i = 0; i < 4; i++) { int temp, j; temp = p.value%T[i] + (p.value/T[i+1])*T[i+1]; if( i == 3) j = 1; else j = 0; for(; j < 10; j++) { t.value = temp + j*T[i]; if(!visit[t.value] && isPrime[t.value]) { visit[t.value] = 1; if(t.value == End) return t.step; Q.push(t); } } } } return -1; } int main() { int N, Ans; getPrime(); scanf("%d", &N); while(N--) { scanf("%d %d", &Start, &End); Ans = BFS(); printf("%d ", Ans); } return 0; }