Mathematics:Prime Path(POJ 3126)

                

                 素数通道

  题目大意:给定两个素数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\n");
 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\n");
 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\n", min_step[sum_tmp]);
110                         return true;
111                     }
112                 }
113             }
114             out[i] = tmp_int;
115         }
116     }
117     return false;
118 }

posted @ 2015-11-29 02:18  PhiliAI  阅读(258)  评论(0编辑  收藏  举报