poj-3126 Prime Path

13 篇文章 0 订阅

    题目描述其实就是篇小故事,不多解释直接说明题意。题意要求给两个4位的素数,求出将前一个素数转化为后一个素数需要的步数。一次只能改变一位数字,且保证每次改变得到的数都是素数

    思路:用BFS暴搜,每次改变一位数如果是素数就进入队列,但是暴搜的前提要把1w以内的素数筛出来。为了方便对每一位上的数的操作,本人用的字符串来储存4位数字。

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <queue>
#define INF 0x3f3f3f3f
#define mod 1000000007

using namespace std;

bool prime[10001];
bool flag[10001];
struct node
{
    char str[6];
    int step;
}turn;
void getprime()
{

    for (int i=2;i*i<=10000;i++)
    {
        if(!prime[i])
            for (int j=i;j*i<=10000;j++)
            {
                prime[i*j]=1;
            }
    }
}
int BFS(char a[],char b[])
{
    if(strcmp(a,b)==0) return 0;
    queue<node>Q;
    int i,j,num,step;
    char x;
    strcpy(turn.str,a);
    turn.step=0;
    num=(turn.str[0]-'0')*1000+(turn.str[1]-'0')*100+(turn.str[2]-'0')*10+turn.str[3]-'0';
    flag[num]=1;
    Q.push(turn);
    while(!Q.empty())
    {
        turn=Q.front();
        step=turn.step;
        Q.pop();
        for (i=0;i<=3;i++)
        {
            x=turn.str[i];
            i==0 ? j='1' : j='0';
            for(;j<='9';j++)
            {
                if(j==x) continue;
                turn.str[i]=j;
                turn.step=step+1;
                if(strcmp(turn.str,b)==0) return turn.step;
                num=(turn.str[0]-'0')*1000+(turn.str[1]-'0')*100+(turn.str[2]-'0')*10+turn.str[3]-'0';
                if(!prime[num]&&!flag[num])
                {
                    flag[num]=1;
                    Q.push(turn);
                }
            }
            turn.str[i]=x;
        }
    }
    return -1;
}
int main()
{
    getprime();
    int t,step;
    char x[6],y[6];
    scanf("%d",&t);
    while(t--)
    {
        memset(flag,0,sizeof(flag));
        scanf("%s%s",x,y);
        step=BFS(x,y);
        printf("%d\n",step);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值