题意:一个4位的素数每次变动一个数位,中间过程也要上素数,问变成另一个的最小步数。
线性筛一遍以后bfs就好。我写的双向,其实没有必要。
#include<cstdio> #include<iostream> #include<string> #include<cstring> #include<queue> #include<vector> #include<stack> #include<vector> #include<map> #include<set> #include<algorithm> #include<cmath> //#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 1e5; bool isNot[maxn]; void seive(int n = maxn-1) { int m = sqrt(n+0.5); for(int i = 2; i <= m; i++){ if(!isNot[i]) for(int j = i*i; j <= n; j += i){ isNot[j] = true; } } isNot[0] = isNot[1] = true; } int d[maxn]; int vis[2][maxn],clk; #define PB push_back #define PS push const int wei[] = {1,10,100,1000}; void doubleBfs(int s,int t) { if(s == t) { puts("0"); return; } queue<int> Q[3]; queue<int> *q1 = Q, *q2 = Q+1, *nxt = Q+2; int *v1 = *vis, *v2 = vis[1]; q1->PS(s); q2->PS(t); v1[s] = ++clk; v2[t] = clk; d[s] = 0; d[t] = 0; while(q1->size() && q2->size()){ if(q1->size()>q2->size()){ swap(q1,q2); swap(v1,v2); } while(q1->size()){ int u = q1->front(); q1->pop(); int dig[4]; for(int i = 0; i < 4; i++){ dig[i] = u/wei[i]%10; } for(int i = 0; i < 4; i++){ int t = u - dig[i]*wei[i]; for(int j = i == 3; j < 10; j++){ if(j != dig[i]){ int v = t+j*wei[i]; if(!isNot[v] && v1[v] != clk){ if(v2[v] == clk) { printf("%d ",d[v]+d[u]+1); return; } d[v] = d[u]+1; nxt->PS(v); v1[v] = clk; } } } } } swap(q1,nxt); } puts("Impossible"); } //#define LOCAL int main() { #ifdef LOCAL freopen("in.txt","r",stdin); #endif seive(); int T; scanf("%d",&T); while(T--){ int a,b; scanf("%d%d",&a,&b); doubleBfs(a,b); } return 0; }