Prime Path (广搜)

来源:互联网 发布:eai 数据黑盒 编辑:程序博客网 时间:2024/05/16 19:00

Prime Path

Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 131072/65536K (Java/Other)
Total Submission(s) : 14   Accepted Submission(s) : 7
Problem 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
31033 81791373 80171033 1033
 

Sample Output
670
 

Source
PKU

题意:

给定两个素数(四位数),求第一个数经过几次转换能够得到第二个素数。转换方式:是变换中某一位的数字(第一位不能为 0,其他的变换数字是 0~9),变换之后的数也为素数!

思路:

广度搜索,首先建立结构体,然后在筛素数,以及得到变换之后的数,这些都单独创建了一个函数,创建队列,符合的进入队列,终止条件是找到第二位数。

代码:

#include <iostream>#include <cstdio>#include <cstring>#include <cstdlib>#include <cmath>#include <queue>#define N 10005using namespace std;int isPrime[N];int v[N];typedef struct{    int bit[5];    int num;    int s;} Node;void go(){    int i,j;    for(i=0;i<N;i++)        isPrime[i]=1;    isPrime[0]=isPrime[1]=0;    for(i=2;i<N;i++)    {        if(isPrime[i]==1)        {            for(j=i+i;j<N;j+=i)            {                isPrime[j]=0;            }        }    }}int getNumber(int a[],int b,int c){    int ans=0;    for(int i=0;i<4;i++)    {        if(i==b)            ans = ans*10+c;        else            ans = ans*10+a[i];    }    return ans;}void bfs(int first,int second){    queue< Node > q;    int i,j,k;    memset(v,0,sizeof(v));    Node front ,rear;    front.num = first;    front.bit[3] = first%10;    front.bit[2] = (first/10)%10;    front.bit[1] = (first/100)%10;    front.bit[0] = (first/1000)%10;    front.s=0;    q.push(front);    while(!q.empty())    {        rear = q.front();        q.pop();        if(rear.num == second)        {            printf("%d\n",rear.s);            break;        }        for(i=0;i<4;i++)        {            for(j=0;j<=9;j++)            {                if(j==0&&i==0) continue;                if(rear.bit[i] == j)                    continue;                else                {                    int number = getNumber(rear.bit,i,j);                    if(isPrime[number]&& !v[number] )                    {                        v[number]=1;                        for(k=0;k<4;k++)                        {                            front.bit[k]=rear.bit[k];                        }                        front.bit[i]=j;                        front.num = number;                        front.s = rear.s+1;                        q.push(front);                    }                }            }        }    }}int main(){    int t;    int n,m;    //freopen("in.txt","r",stdin);    go();    scanf("%d",&t);    while(t--)    {        scanf("%d%d",&n,&m);        bfs(n,m);    }    return 0;}
心得:

区分开深搜和广搜。两者的根本区别。。

原创粉丝点击