题目链接:http://poj.org/problem?id=3126
题意:现给出一个四位数,要求每次只能改变个十百千中的一位,在每次改变之后这个这个数必须是素数,求改变成指定数字的最少改变次数。
#include <iostream> #include <cstdlib> #include <cstdio> #include <algorithm> #include <vector> #include <queue> #include <cmath> #include <stack> #include <cstring> using namespace std; #define INF 0xfffffff #define maxn 10000 int p[maxn], v[maxn]; struct node { int x, step; }; int prime(int n) { int i, k=sqrt(n); for(i=2; i<=k; i++) if(n %i == 0) return 0; return 1; } /* 学长的Turn: int Turn(int n, int k) { char s[10]={0}; sprintf(s, "%d", n); s[k] = '0'; sscanf(s, "%d", &n); return n; } */ int Turn(int n, int k) { int a, b, c; if(k==0) { n %= 1000; } else if(k==1) { a = n /1000; b = n %1000; c = b %100; n = a*1000+c; } else if(k==2) { a = n/1000; b = n%1000; c = b/100; b = b%10; n = a*1000+c*100+b; } else { a = n / 10; n = a * 10; } return n; } int BFS(int x, int y) { queue<node>Q; node begins, now, next; begins.x = x; begins.step = 0; Q.push(begins); while(Q.size()) { now = Q.front(); Q.pop(); if(now.x == y) return now.step; int t = 1000, q; for(int i=0; i<4; i++) { q = Turn(now.x, i); for(int j=0; j<10; j++) { next.x = q + j * t; if(p[next.x] && !v[next.x]) { next.step = now.step + 1; v[next.x] = 1; Q.push(next); } } t /= 10; } } return -1; } int main() { int i, T, s, e; memset(p, 0, sizeof(p)); for(i=1000; i<maxn; i++) p[i] = prime(i); scanf("%d", &T); while(T --) { scanf("%d %d", &s, &e); memset(v, 0, sizeof(v)); int ans = BFS(s, e); if(ans == -1) printf("Impossible\n"); else printf("%d\n", ans); } return 0; }