POJ 3126 Prime Path

       题意:将一个初始数字变成目标数字,每次只能改变一个数字,并且保证每一个改变后的数字是是素数,求最少的步数。

分析:一般求最少步数都是用广搜,这是个简单广搜。

代码:

#include<iostream>
using namespace std;
#define maxn 1000000
int que[maxn],first,rear;
int inque[10000]; //表示这个数是否访问过了并且存储步数 
bool Isprime(int a) //判断一个数是否是素数 
{
     for(int i=2; i*i<=a; i++)
             if( a%i==0)
                 return false;
     return true;
}
void Solve(int i,int a,int temp,int num) 
{
     if( i!=a&&!inque[temp-1000]&&Isprime(temp)){ //如果此数没有访问过标志并设置为num的下一步。 
                     inque[temp-1000]=inque[num-1000]+1;
                     que[rear++]=temp;
     }
}
int BFS(int start,int goal)  //广搜遍历寻找 最短的路径 
{
     int i,temp,num,cnt,a,pt;
     first=rear=0;
     cnt=0; pt=0;
     memset(que,0,sizeof(que));
     memset(inque,0,sizeof(inque));
     que[rear++]=start;
     inque[start]=1;
     while( first!=rear){
            num=que[first++];
            if( num==goal)
                return inque[goal-1000];
            for( i=0; i<=9; i++){
                 if( i!=0){ //改变首位,不为0 
                     a=num/1000;
                     temp=num-a*1000+i*1000;
                     Solve(i,a,temp,num);
                 }
                 
                 a=num%1000;  //第二位 
                 if(a/100) a/=100;
                 else a=0;
                 temp=num-a*100+i*100;
                 Solve(i,a,temp,num);
                 
                 a=num%100;  //第三位 
                 if(a/10) a/=10;
                 else a=0;
                 temp=num-a*10+i*10;
                 Solve(i,a,temp,num);
                  
                 a=num%10;   //第四位 
                 temp=num-a+i;
                 Solve(i,a,temp,num);        
            }
     }
}

int main()
{
    int s,t,g;
    scanf("%d",&t);
    while( t--){
           scanf("%d%d",&s,&g);
           if( s==g)
               printf("0\n");
           else
               printf("%d\n",BFS(s,g));
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值