题目描述

  • 题意就是把一个四位的质数转化为另一个四位的质数,每次只能改变一位数字,且改变后仍要是质数,问最少需要多少次转化
    一开始代码写的很粗糙
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    #include <iostream>
    #include <string.h>
    #include <vector>
    #include <queue>
    #include <cmath>
    using namespace std;

    const int N = 10000;
    bool a[N + 1];
    vector<int> prime;
    void get_prime() {
    memset(a, true, sizeof(a));
    for (int i = 2; i <= N; i++) {
    if (a[i]) prime.push_back(i);
    for (int j = 0; j < prime.size() && i * prime[j] <= N; j++) {
    a[i * prime[j]] = false;
    if (i % prime[j]==0) break;
    }
    }
    }

    struct Node{
    int number;
    int money;
    };

    queue<Node>qu;
    int start,ended;
    int vis[N] = {0};
    void bfs()
    {
    int bit,i,j,k,temp;
    Node first_node;
    Node temp_node;
    Node now_node;

    first_node.number = start;
    first_node.money = 0;
    qu = queue<Node>();
    qu.push(first_node);
    memset(vis,0,sizeof(vis));
    while(!qu.empty()) {
    now_node = qu.front();
    if (now_node.number == ended) {
    cout << now_node.money << endl;
    return;
    }
    temp = now_node.number;
    for (i = 0; i < 3; i++) { //个位十位百位
    bit = temp%10;
    for (j = bit + 1, k = 1; j < 10; j++, k++) { //增大
    if (a[now_node.number + k * (int) pow(10, i)] && !vis[now_node.number + k * (int) pow(10, i)]) {
    temp_node.number = now_node.number + (int) k * pow(10, i);
    temp_node.money = now_node.money + 1;
    vis[temp_node.number] = 1;
    qu.push(temp_node);
    }
    }
    for (j = bit - 1, k = 1; j >= 0; k++, j--) { /*减小*/
    if (a[now_node.number - k * (int) pow(10, i)] && !vis[now_node.number - k * (int) pow(10, i)]) {
    temp_node.number = now_node.number - (int) k * pow(10, i);
    temp_node.money = now_node.money + 1;
    vis[temp_node.number] = 1;
    qu.push(temp_node);
    }
    }
    temp/=10;
    }
    /*千位*/
    bit = temp%10;
    for (j = bit + 1, k = 1; j < 10; j++, k++){
    if (a[now_node.number + 1000 * k] && !vis[now_node.number + 1000 * k]) {
    temp_node.number = now_node.number+1000*k;
    temp_node.money = now_node.money+1;
    vis[temp_node.number] = 1;
    qu.push(temp_node);
    }
    }
    for (j = bit - 1, k = 1; j > 0; j--, k++) {
    if (a[now_node.number - 1000 * k] && !vis[now_node.number - 1000 * k]) {
    temp_node.number = now_node.number - 1000 * k;
    temp_node.money = now_node.money + 1;
    vis[temp_node.number] = 1;
    qu.push(temp_node);
    }
    }
    qu.pop();
    }
    }

    int main() {
    int k,i;

    get_prime();
    cin>>k;
    for(i=0;i<k;i++){
    cin>>start>>ended;
    bfs();
    }
    return 0;
    }
    转化的过程写的十分繁琐
    于是学习了http://www.cnblogs.com/liuxin13/p/4648717.html
    的代码
    搬运一下
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <cmath>
    #include <queue>

    #define maxn 10000
    using namespace std;

    int p[maxn];

    int Prime(int n)
    {
    int i,k=sqrt(n);

    for(i=2;i<=k;i++) {
    if (n % i == 0)
    return 0;
    }
    return 1;
    }

    int Turn(int n,int k)
    {
    char s[10] = {0};

    sprintf(s,"%d",n);
    s[k] = '0';
    sscanf(s,"%d",&n);
    return n;
    }

    int BFS(int s,int e)
    {
    int i,j,k,q;
    int v[maxn] = {0};
    queue<int> Q;

    Q.push(s);
    v[s] = 1;
    while(!Q.empty()){
    s = Q.front();
    if(s==e)
    return v[s] - 1;
    int t=1000;
    for(i=0;i<4;i++){
    q = Turn(s,i);
    for(k=0;k<10;k++){
    j=q+k*t;
    if(p[j]==1 && v[j]==0){
    Q.push(j);
    v[j] = v[s]+1;
    }
    }
    t/=10;
    }
    Q.pop();
    }
    return -1;
    }

    int main() {
    int i,s,e,T,ans;

    for(i=1000;i<maxn;i++)
    p[i] = Prime(i);
    scanf("%d",&T);
    while(T--){
    scanf("%d%d",&s,&e);
    ans = BFS(s,e);
    if(ans==-1)
    printf("Impossible\n");
    else
    printf("%d\n",ans);
    }
    return 0;
    }
  • Turn()中先利用sprintf()把int型变量n写到字符数组s中,然后把s的第k位设为’0’,再用ssprintf()把s转化为整形,从而实现转化
  • 求质数表可以用我一开始那段代码的线筛,效率更高