poj3126 埃式筛法+bfs

来源:互联网 发布:potplayer for mac 编辑:程序博客网 时间:2024/06/05 15:28

题意:求素数a变换到素数b的最小步数,每次只能更改一位,且更改后的数也是素数。每次输入的两个素数都是4位数。

解法一:利用埃式筛法打表,用数组记录素数,把所有素数放在一个数组中,然后在这个数组的基础上进行bfs。

解法二:打表记录每个数的素数性质,然后将a的每一位依次改变,进行bfs,前面的打表在bfs中作为一个判断条件。

解法一代码:

/*@Filename: test.cpp@Version:  1.0@Author:   wyl6@Email:    17744454343@163.com*/#include <cstdio>  #include <cstdlib>  #include <iostream>  #include <stack>  #include <queue>  #include <algorithm>  #include <cstring>  #include <string>  #include <cmath>  #include <vector>  #include <bitset>  #include <list>  #include <sstream>  #include <set>  #include <map>#include <functional>  using namespace std;    #define INF 0x3f3f3f3f  #define maxn 10000typedef long long ll;  typedef pair<int,int> pa;int p;int prime[maxn];bool is_prime[maxn];bool used[maxn];bool change(int x,int y){    int i = 0;    while(x != 0){        if(x%10 == y%10) i++;        x /= 10;        y /= 10;    }    if(i == 3) return true;    return false;}void bfs(int s,int end){    queue <pa> que;//first序号,second深度    que.push(pa(s,0));    memset(used,0,sizeof(used));    used[s] = true;    while(!que.empty()){        pa e = que.front(); que.pop();        for (int i = 0; i < p ; ++i){            if (change(prime[e.first],prime[i]) && !used[i]){                if(prime[i] == prime[end]){                    cout << e.second+1 << endl;                    return;                }                used[i] = true;                que.push(pa(i,e.second+1));            }        }    }    printf("Impossible\n");}int main()  {      //埃式筛法打表    p =  0;    for (int i = 0; i < maxn; ++i) is_prime[i] = true;    is_prime[0] = is_prime[1] = false;    for (int i = 2; i < maxn; ++i) {        if (is_prime[i]){            prime[p++] = i;            for (int j = 2*i; j < maxn; j += i) is_prime[j] = false;        }    }    int n;    cin >> n;    while(n--){        int a,b,s,end;        cin >> a >> b;        for (int i = 0; i < p; ++i){            if(prime[i] == a) s = i;             if(prime[i] == b) end = i;        }        if (s == end) printf("0\n");        else bfs(s,end);    }    return 0;  }  

解法二代码:

#include <cstdio>  #include <cstdlib>  #include <iostream>  #include <stack>  #include <queue>  #include <algorithm>  #include <cstring>  #include <string>  #include <cmath>  #include <vector>  #include <bitset>  #include <list>  #include <sstream>  #include <set>  #include <map>#include <functional>  using namespace std;  #define maxn 10000typedef pair<int,int> pa;bool is_prime[maxn];int used[maxn];void bfs(int s,int end){    queue <pa> que;//first序号,second深度    que.push(pa(s,0));    memset(used,0,sizeof(used));    used[s] = true;    while(!que.empty()){        pa e = que.front(); que.pop();        for (int i = 1; i <= 1000; i *= 10){            for (int j = 0; j < 10; ++j){                int sum = e.first%i+e.first/(i*10)*(i*10)+i*j;                if(i == 1000 && j == 0) continue;                if(sum == end){                    printf("%d\n",e.second+1); return;                 }                 if (is_prime[sum] && !used[sum]){                    used[sum] = 1;                    que.push(pa(sum,e.second+1));                }            }        }    }    printf("Impossible\n");}int main()  {      for (int i = 0; i < maxn; ++i) is_prime[i] = true;    is_prime[0] = is_prime[1] = false;    for (int i = 2; i < maxn; ++i) {        if (is_prime[i]){            for (int j = 2*i; j < maxn; j += i) is_prime[j] = false;        }    }    int n;    scanf("%d",&n);    while(n--){        int a,b;        scanf("%d%d",&a,&b);        if (a == b) printf("0\n");        else bfs(a,b);    }    return 0;  }  

p.s.

易错点一:埃式筛法时忘了考虑数组边界,越界造成runtime error

易错点二:初始化问题

易错点三:循环的上下界