poj3126 - Prime Path(BFS)

本文解析了如何使用广度优先搜索(BFS)算法解决素数变换问题,具体为将一个四位素数通过改变一位数字的方式转换成另一个素数,同时确保每一步变换后的数仍为素数。文章详细介绍了算法的实现过程,包括素数判断、队列操作及状态记录等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:http://poj.org/problem?id=3126

题意:给定两个素数n和m,要求把n变成m,每次变换时只能变一个数字,即变换后的数与变换前的数只有一个数字不同,并且要保证变换后的四位数也是素数。求最小的变换次数;如果不能完成变换,输出Impossible。

思路:广搜枚举每一位数字加入队列(个位1-9的奇数,十位,百位0-9,的数字,千位1-9的数字),能得到答案就一定是最少的次数,否则就输出Impossible。

AC代码:

#include <iostream>
#include <queue>
#include <math.h>
#include <stdio.h>
#include <string.h>
using namespace std;
const int maxn = 1e5+7;
int vis[maxn], n, m, t;
struct node
{
    int x, step;
}now, tmp, nex;
int is_prime(int x)
{
    for(int i = 2; i <= sqrt(x); i++)
        if(x % i == 0) return 0;
    return 1;
}
queue <node> Q;
void bfs()
{
    while(!Q.empty())
    {
        tmp = Q.front();
        int x = tmp.x; Q.pop();
        if(x == m) {printf("%d\n",tmp.step); return; }
        for(int i = 1; i < 10; i += 2)
        {
            int y = x / 10 * 10 + i;
            if(x != y && !vis[y] && is_prime(y))
            {
               nex.x = y; nex.step = tmp.step + 1;
               Q.push(nex); vis[y] = 1;
            }
        }
        for(int i = 0; i < 10; i++)
        {
            int y = x / 100 * 100 + i * 10 + x % 10;
            if(x != y &&!vis[y] && is_prime(y))
            {
               nex.x = y; nex.step = tmp.step + 1;
               Q.push(nex); vis[y] = 1;
            }
        }
        for(int i = 0; i < 10; i++)
        {
            int y = x / 1000 * 1000 + i * 100 + x % 100;
            if(x != y &&!vis[y] && is_prime(y))
            {
               nex.x = y; nex.step = tmp.step + 1;
               Q.push(nex); vis[y] = 1;
            }
        }
        for(int i = 1; i < 10; i++)
        {
            int y = i * 1000 + x % 1000;
            if(x != y &&!vis[y] && is_prime(y))
            {
               nex.x = y; nex.step = tmp.step + 1;
               Q.push(nex); vis[y] = 1;
            }
        }
    }
    puts("Impossible");
    return;
}
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        while(!Q.empty()) Q.pop();
        memset(vis, 0, sizeof(vis));
        scanf("%d%d",&n,&m); vis[n] = 1;
        now.x = n, now.step = 0;
        Q.push(now); bfs();
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值