poj 3162 Prime Path

27 篇文章 0 订阅
3 篇文章 0 订阅
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

思路:典型的深搜+剪枝+打表

代码:

Memory: 812 KB Time: 16 MSLanguage: G++ Result: Accepted Auther:Morezy


      
      
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <queue>
#include <stack>
#include <vector>
#include <cmath>

using namespace std;
int a[4];
int prime[10000] = {0};//
int visit[10000];
int front,rear,g,flag;
struct node
{
    int x;
    int pre;
}p[10000000];
vector<node>r;
void Is_Prime()//素数打表
{
    int i,j;
    for ( i = 1001; i <= 9997; i++)
    {
         if(i % 2 == 0)
         {
             continue;
         }
         for (j = 3; j*j <= i; j += 2)
         {
             if(i % j  == 0)
             {
                 break;
             }
         }
         if(j*j > i)
         {
          prime[i] = 1;
         }
    }
}
void solve(int x)//把数放到长度为4的数组中
{
    int i = 0;
    while (x)
    {
      a[i] = x%10;
      x /= 10;
      i++;
    }
}
int bfs(int x1, int y1)
{
      front  = rear = 0;
      p[front].x = x1;
      p[front].pre = 0;
      rear++;
      r.push_back(p[front]);
      while (front < rear)
      {
          for(int j = 0; j < 4; j++)
          {
              for(int i = 0; i <= 9; i++)
              {
                    int sum = 0;
                    node s  = p[front];
                    solve(s.x);//处理队列第一个

                if(j== 3 && i == 0)//千位不能为0
                {
                    continue;
                }
                if( j == 3 && i > g)
                {
                    break;
                }
                    a[j] = i;
                    sum  = a[0]+a[1]*10+a[2]*100+a[3]*1000;
                    //原来条件里面还写了sum>s.x,sum<= y1,事实上变化的数是可以大于的。。。。
                    if(prime[sum]&& !visit[sum])//符合条件就换数
                    {
                        visit[sum] = 1;
                        p[rear].x = sum;

           
           
  //原来写成p[rear].pre = front;调试了好久。。。
p[rear].pre = p[front].pre+1; rear++;//入队 } if(sum == y1) { flag = 0; return p[front].pre+1; } } } front++;//出队 } } int main() { int t,x,y,count; scanf("%d",&t); Is_Prime(); while (t--) { memset(visit,0,sizeof(visit)); scanf("%d%d",&x,&y); flag = 1; if(x == y) { cout << 0 << endl; continue; } solve(y); g = a[3]; count = bfs(x,y); if(flag) { cout <<"Impossible"<< endl; } else { cout <<count<< endl; } } return 0; }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值