题目大意:给定两个素数a,b,要你找到一种变换,使得每次变换都是素数,如果能从a变换到b,则输出最小步数,否则输出Impossible
水题,因为要求最小步数,所以我们只需要找到到每个素数的最小步数就可以了,每个权都是1,所以用BFS就可以了,一开始我还用DFS,太丢人了,一开始就把素数表打好就可以了
1 #include <iostream> 2 #include <functional> 3 #include <algorithm> 4 5 using namespace std; 6 7 typedef int Position; 8 typedef struct _set 9 { 10 char num[4]; 11 }Set,Queue; 12 bool BFS(const int); 13 void Search_Prime(void); 14 int Get_Num(char *); 15 16 static bool prime_set[10000]; 17 static char num[4], goal_set[4]; 18 static int min_step[10000], pow_sum[4] = { 1, 10, 100, 1000 }; 19 static void Push(char *,Position); 20 static char *Pop(Position); 21 Queue que[2 * 10000]; 22 23 int main(void) 24 { 25 int case_sum, goal_num; 26 27 Search_Prime(); 28 scanf("%d", &case_sum); 29 30 while (case_sum--) 31 { 32 getchar(); 33 scanf("%c%c%c%c", &num[0], &num[1], &num[2], &num[3]); 34 getchar(); 35 scanf("%c%c%c%c", &goal_set[0], &goal_set[1], &goal_set[2], &goal_set[3]); 36 goal_num = Get_Num(goal_set); 37 if (!BFS(goal_num)) 38 printf("Impossible "); 39 } 40 41 return 0; 42 } 43 44 int Get_Num(char *s) 45 { 46 int ans = 0; 47 for (int i = 0; i < 4; i++) 48 ans += (s[3 - i] - '0') * pow_sum[i]; 49 return ans; 50 } 51 52 void Search_Prime(void)//线筛法打表 53 { 54 int i, j; 55 prime_set[1] = 1; 56 memset(prime_set, 0, sizeof(prime_set)); 57 for (i = 2; i < 10000; i++) 58 { 59 for (j = 2; j <= i && i*j < 10000; j++) 60 if (!prime_set[j]) 61 prime_set[i*j] = 1; 62 } 63 } 64 65 static void Push(char *num, Position back) 66 { 67 for (int i = 0; i < 4; i++) 68 que[back].num[i] = num[i]; 69 } 70 71 static char *Pop(Position head) 72 { 73 return que[head].num; 74 } 75 76 bool BFS(const int goal) 77 { 78 memset(min_step, -1, sizeof(min_step)); 79 Position head = 0, back = 0; 80 int i, j, sum_tmp, step_now; 81 char *out, tmp_int; 82 83 sum_tmp = Get_Num(num); 84 if (sum_tmp == goal) 85 { 86 printf("0 "); 87 return true; 88 } 89 Push(num, back++); min_step[sum_tmp] = 0; 90 91 while (head != back) 92 { 93 out = Pop(head++); sum_tmp = Get_Num(out); 94 step_now = min_step[sum_tmp]; 95 for (i = 0; i < 4; i++) 96 { 97 tmp_int = out[i]; 98 for (j = 0; j < 10; j++) 99 { 100 if (i == 0 && j == 0 || tmp_int == j + '0') continue; 101 out[i] = j + '0'; 102 sum_tmp = Get_Num(out); 103 if (min_step[sum_tmp] == -1 && !prime_set[sum_tmp]) 104 { 105 min_step[sum_tmp] = step_now + 1; 106 Push(out, back++); 107 if (sum_tmp == goal) 108 { 109 printf("%d ", min_step[sum_tmp]); 110 return true; 111 } 112 } 113 } 114 out[i] = tmp_int; 115 } 116 } 117 return false; 118 }