zoukankan      html  css  js  c++  java
  • POJ 3216 Prime Path(打表+bfs)

    Prime Path
    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 27132   Accepted: 14861

    Description

    The ministers of the cabinet were quite upset by the message from the Chief of Security stating that they would all have to change the four-digit room numbers on their offices.
    — It is a matter of security to change such things every now and then, to keep the enemy in the dark.
    — But look, I have chosen my number 1033 for good reasons. I am the Prime minister, you know!
    — I know, so therefore your new number 8179 is also a prime. You will just have to paste four new digits over the four old ones on your office door.
    — No, it’s not that simple. Suppose that I change the first digit to an 8, then the number will read 8033 which is not a prime!
    — I see, being the prime minister you cannot stand having a non-prime number on your door even for a few seconds.
    — Correct! So I must invent a scheme for going from 1033 to 8179 by a path of prime numbers where only one digit is changed from one prime to the next prime.

    Now, the minister of finance, who had been eavesdropping, intervened.
    — No unnecessary expenditure, please! I happen to know that the price of a digit is one pound.
    — Hmm, in that case I need a computer program to minimize the cost. You don't know some very cheap software gurus, do you?
    — In fact, I do. You see, there is this programming contest going on... Help the prime minister to find the cheapest prime path between any two given four-digit primes! The first digit must be nonzero, of course. Here is a solution in the case above.
    1033
    1733
    3733
    3739
    3779
    8779
    8179
    The cost of this solution is 6 pounds. Note that the digit 1 which got pasted over in step 2 can not be reused in the last step – a new 1 must be purchased.

    Input

    One line with a positive number: the number of test cases (at most 100). Then for each test case, one line with two numbers separated by a blank. Both numbers are four-digit primes (without leading zeros).

    Output

    One line for each case, either with a number stating the minimal cost or containing the word Impossible.

    Sample Input

    3
    1033 8179
    1373 8017
    1033 1033

    Sample Output

    6
    7
    0

    Source

     
     
    题目意思:
    给出两个四位数的素数,要求对第一个素数进行一系列操作,使他变成第二个四位数的素数,每次操作只能改变一位数,且要求每次操作之后的数仍然是素数
    问你最少的操作步骤数是多少?
     
    分析:
    先对四位数的素数打一个表
    然后bfs
    需要注意的是每次搜索入队之后,要进行回退操作
    注意设置标记位(该数已经搜索过)
     
    code:
    #include<stdio.h>
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    #include <math.h>
    #include <cstdlib>
    #include <queue>
    using namespace std;
    #define max_v 10100
    int prime[max_v];
    int vis[max_v];
    struct node
    {
        int x,step;
    };
    void init()//打N以内的素数表,prime[i]=0为素数。
    {
        memset(prime,0,sizeof(prime));
        prime[1]=1;
        for(int i=2; i<max_v; i++)
        {
            if(prime[i]==0)
            {
                for(int j=2; j*i<max_v; j++)
                    prime[j*i]=1;
            }
        }
    }
    int bfs(int s,int e)
    {
        int num;
        memset(vis,0,sizeof(vis));//vis[N]用来标记是否查找过
        queue<node> q;
    
        node p,next;
    
        p.x=s;
        p.step=0;
    
        vis[s]=1;
        q.push(p);
    
        while(!q.empty())
        {
            p=q.front();
            q.pop();
    
            if(p.x==e)
            {
                return p.step;
            }
            int t[5];
            t[1]=p.x/1000;//
            t[2]=p.x/100%10;//
            t[3]=p.x/10%10;//
            t[4]=p.x%10;//
    
            for(int i=1; i<=4; i++)
            {
                int temp=t[i];//这里特别注意,每次只能变换一位数,这里用来保存该变换位的数,变换下一位数时,该位数要恢复
                for(int j=0; j<10; j++)
                {
                    if(t[i]!=j)
                    {
                        t[i]=j;//换数
                        num=t[1]*1000+t[2]*100+t[3]*10+t[4];
                    }
                    if(num>=1000&&num<=9999&&vis[num]==0&&prime[num]==0)//满足要求,四位数,没有用过,是素数
                    {
                        next.x=num;
                        next.step=p.step+1;
                        q.push(next);
                        vis[num]=1;
                    }
                }
                t[i]=temp;//恢复
            }
        }
        return -1;
    }
    int main()
    {
        //题意:给你两个4位数,要求你每次只能变换一位数字,并且变换前后的数字都要满足是素数;求最少变换次数;
        //首先打好素数表,再进行BFS
        int n,a,b,ans;
        init();
        cin>>n;
        while(n--)
        {
            cin>>a>>b;
            ans=bfs(a,b);
            if(ans==-1)
            {
                cout<<"Impossible"<<endl;
            }
            else
            {
                cout<<ans<<endl;
            }
        }
        return 0;
    }
  • 相关阅读:
    Cogs 465. 挤牛奶
    洛谷P1083 借教室
    Cogs 1264. [NOIP2012] 开车旅行(70分 暴力)
    2017-10-19 NOIP模拟赛
    Codevs 2144 砝码称重 2
    洛谷P1450 [HAOI2008]硬币购物
    洛谷P2534 [AHOI2012]铁盘整理
    洛谷P1731 生日蛋糕
    2017-10-18 NOIP模拟赛
    洛谷P1074 靶形数独
  • 原文地址:https://www.cnblogs.com/yinbiao/p/9391721.html
Copyright © 2011-2022 走看看