给定两个四位素数a b,要求把a变换到b
变换的过程要保证 每次变换出来的数都是一个 四位素数,而且当前这步的变换所得的素数 与 前一步得到的素数 只能有一个位不同,而且每步得到的素数都不能重复。
求从a到b最少需要的变换次数。无法变换则输出Impossible
输入:
第一行 是一个数T 表示下面有T个测试数据
下面T行 每行两个数a b
解题思路:每次变换一次,个十百千,四个位置上的数每个从0-9循环一边一共需要4 * 10 = 40次循环 剪枝之后就没多少了 所以直接暴力BFS能过
下面是代码
#include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <cstdlib> #include <cmath> #include <cctype> #define N 10000 #define MAXV 10000 using namespace std; bool Prime[11000];//Prime[i] = false证明 i 是素数 void MakePrime()//对素数打表 { int i, j; for(i = 1000; i <= N; i++) { for(j = 2; j < i; j++) { if(i % j == 0) { Prime[i] = false; break; } } if(j == i) Prime[i] = true; } } void BFS(int s, int e) { bool maps[N]; //用来记录此数是不是已经变换过 int step[N], d[4], temp, e_temp, i, j; //d代表个十百千四个位置,step[i]用来储存变换为 i 时一共变换了几次 queue<int>q; memset(step, 0, sizeof(step)); memset(maps, false, sizeof(maps)); q.push(s); maps[s] = true; while(!q.empty()) { s = q.front(); q.pop(); d[0] = s % 10;//个 d[1] = s / 10 % 10;//十 d[2] = s / 100 % 10;//百 d[3] = s / 1000;//千 for(i = 0; i < 4; i++) { //四个位置 temp = d[i]; //原本在此位置的数字 先用temp保存 因为后面如果改变的是其他位置这个位置不变 for(j = 0; j < 10; j++) { //0-9十个数 if(temp != j) { //自己不需要再次判断 d[i] = j; e_temp = d[0] + d[1] * 10 + d[2] * 100 + d[3] * 1000; if(!maps[e_temp] && Prime[e_temp]) { //判断这个数有没有判断过,是不是质数 maps[e_temp] = true; step[e_temp] = step[s] + 1; q.push(e_temp); } if(e_temp == e) { //查找到 输出转换次数 printf("%d ", step[e_temp]); return; } } d[i] = temp; } } if(s == e) { printf("%d ", step[s]); return; } } //所有的数都变换过 无法得到结果 printf("Impossible "); } int main() { MakePrime(); int start, end, T; scanf("%d", &T); while(T--) { scanf("%d %d", &start, &end); BFS(start, end); } }