POJ 3126 Prime Path BFS 广度优先搜索 素数

/*
---------------------------------------
    stratege : 素数判断(先打表), BFS
    Author : Johnsondu


    Problem: 3126		User: a312745658
    Memory: 276K		Time: 47MS
    Language: C++		Result: Accepted
----------------------------------------
*/

#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
#include <algorithm>
using namespace std ;

int a[10000] ;
int x, y ;
bool mark[10000] ;
bool flag ;
int num ;

struct Node
{
    int t, h, d, s ;  //千位,百位,十位和各位
    int step, cnt ;   //step记录时间,cnt 表示当前数
}cur, next ;

//初始化
void init ()
{
    flag = false ;
    memset (mark, false, sizeof(mark)) ;
}

void BFS ()
{
    int i, j, k ;
    cur.t = x / 1000 ;
    cur.h = x % 1000 / 100 ;
    cur.d = x % 100 / 10 ;
    cur.s = x % 10 ;
    cur.step = 0 ;
    cur.cnt = x ;
    queue <Node> Q ;
    Q.push (cur) ;
    mark[cur.cnt] = true ;
    while (!Q.empty())
    {
        cur = Q.front () ;
        Q.pop () ;

        if (cur.cnt == y)
        {
            flag = true ;
            num = cur.step ;
            while (!Q.empty())
                Q.pop () ;
            return ;
        }

        for (i = 1; i < 10; i ++)    //千位,注意不能为0,故循环从1开始,其他位从0开始
        {
            if (cur.t != i)
            {
                next.t =  i ;
                next.h =  cur.h  ;
                next.d = cur.d ;
                next.s = cur.s ;
                next.cnt = next.t*1000 + next.h*100 + next.d*10 + next.s ;
                if (a[next.cnt] == 0 && !mark[next.cnt])  //next.cnt 是素数,且以前没走过
                {
                    mark[next.cnt] = true ;
                    next.step = cur.step + 1;
                    Q.push (next) ;
                }
            }
        }
        for (i = 0; i < 10; i ++)
        {
            if (cur.h != i)
            {
                next.t = cur.t ;
                next.h = i ;
                next.d = cur.d ;
                next.s = cur.s ;
                next.cnt = next.t*1000 + next.h*100 + next.d*10 + next.s ;
                if (a[next.cnt] == 0 && !mark[next.cnt])
                {
                    mark[next.cnt] = true ;
                    next.step = cur.step + 1;
                    Q.push (next) ;
                }
            }
        }
        for (i = 0; i < 10; i ++)
        {
            if (cur.d != i)
            {
                next.t = cur.t ;
                next.h = cur.h ;
                next.d = i ;
                next.s = cur.s ;
                next.cnt = next.t*1000 + next.h*100 + next.d*10 + next.s ;
                if (a[next.cnt] == 0 && !mark[next.cnt])
                {
                    mark[next.cnt] = true ;
                    next.step = cur.step + 1;
                    Q.push (next) ;
                }
            }
        }
        for (i = 0; i < 10; i ++)
        {
            if (cur.s != i)
            {
                next.t = cur.t ;
                next.h = cur.h ;
                next.d = cur.d ;
                next.s = i ;
                next.cnt = next.t*1000 + next.h*100 + next.d*10 + next.s ;
                if (a[next.cnt] == 0 && !mark[next.cnt])
                {
                    mark[next.cnt] = true ;
                    next.step = cur.step + 1;
                    Q.push (next) ;
                }
            }
        }
    }


}

int main()
{
    int i, j, k, tmp ;
    int  tcase, ans ;

    memset (a, 0, sizeof(a)) ;
    
    //素数标记
    for (i = 2; i < 10000; i ++)
    {
        if (a[i] == 0)
        {
            tmp = 2 * i ;
            while (tmp < 10000)
            {
                a[tmp] = 1 ;
                tmp += i ;
            }
        }
    }

    cin >> tcase ;
    while (tcase --)
    {
        cin >> x >> y ;
        init () ;
        BFS () ;
        if (flag)
            printf ("%d\n", num) ;
        else
            printf ("Impossible\n") ;
    }
    return 0 ;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值