POJ 3126 Prime Path

5 篇文章 0 订阅

原题链接:

http://poj.org/problem?id=3126

题目大意:

先输入一个n(n不超过100)。表示有n组的测试样例。然后输入两个素数。第一个表示起始数。第二个表示目标数。问要多少是操作才可以把第一个数变成第二个数。
操作要求:
1.每次操作后的数必须是素数
2.每次操作只能改动一个数字
如果可以输出需要多少次。不行输出“Impossible”

思路:

采用一种笨办法:
从-9~9每个计算过去小于0或者大于9都舍去。然后判断是不是素数
其他的和一般的BFS类似

代码如下:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <cmath>

using namespace std;

int T;
int Start,End;
int Check[10005];
int Pre[10005];
int number;
int Change[18]={-9,-8,-7,-6,-5,-4,-3,-2,-

1,1,2,3,4,5,6,7,8,9};
bool Find;

bool is_prime(int n)
{
    int result = 0;
    int i;
    if (n <= 1)
    {
        return result;
    }
    if(2 == n)
    {
        result = 1;
        return result;
    }
    for (i = 2; i < n ;i++)
    {
        if (0 == n % i)
        {
            result = 0;
            break;
        }
        else if (i + 1 == n)
        {
            result = 1;
        }
        else
        {
            continue;
        }
    }
    return result;
}


void GetCount( int Index )
{
    while( Pre[Index] != -1 )
    {
        Index = Pre[Index];
        number++;
    }

}

bool IsNumberLeagal( int x )
{
    if( x < 0 || x > 9 )
        return false;
    return true;
}

bool IsLeagal( int Index )
{
    if( Index < 1000 || Index > 9999 )
        return false;
    return true;
}
void bfs()
{
    queue<int> Path;
    memset( Check,0,sizeof( Check ) );
    memset( Pre,0,sizeof( Pre ) );

    Check[Start] = 1;
    Pre[Start] = -1;
    Path.push ( Start );

    int Now,Next,fir,sec,thr,fou;
    int i,nfir,nsec,nthr,nfou;
    while( !Path.empty () )
    {
        Now = Path.front ();
        Path.pop ();

        fir = ( Now % 10000 ) /1000;
        sec = ( Now % 1000 ) /100;
        thr = ( Now % 100 ) /10;
        fou = ( Now % 10 ) /1;


        for( i = 0; i < 18; i++ )
        {
            nfir = fir + Change[i];
            if( !IsNumberLeagal( nfir ) )
                continue;
            Next = nfir *1000 + sec *100 + thr 

*10 + fou *1;
            if( IsLeagal( Next ) && !Check

[Next] && is_prime( Next ) )
            {
                Check[Next] = 1;
                Pre[Next] = Now;
                if( Next == End )
                {
                    Find = true;
                    GetCount( Next );
                    return ;
                }
                Path.push ( Next );
            }
        }

        for( i = 0; i < 18; i++ )
        {
            nsec = sec + Change[i];
            if( !IsNumberLeagal( nsec ) )
                continue;
            Next = fir *1000 + nsec *100 + thr 

*10 + fou *1;
            if( IsLeagal( Next ) && !Check

[Next] && is_prime( Next ) )
            {
                Check[Next] = 1;
                Pre[Next] = Now;
                if( Next == End )
                {
                    Find = true;
                    GetCount( Next );
                    return ;
                }
                Path.push ( Next );
            }
        }
        for( i = 0; i < 18; i++ )
        {
            nthr = thr + Change[i];
            if( !IsNumberLeagal( nthr ) )
                continue;
            Next = fir *1000 + sec *100 + nthr 

*10 + fou *1;
            if( IsLeagal( Next ) && !Check

[Next] && is_prime( Next ) )
            {
                Check[Next] = 1;
                Pre[Next] = Now;
                if( Next == End )
                {
                    Find = true;
                    GetCount( Next );
                    return ;
                }
                Path.push ( Next );
            }
        }
        for( i = 0; i < 18; i++ )
        {
            nfou = fou + Change[i];
            if( !IsNumberLeagal( nfou ) )
                continue;
            Next = fir *1000 + sec *100 + thr 

*10 + nfou *1;
            if( IsLeagal( Next ) && !Check

[Next] && is_prime( Next ) )
            {
                Check[Next] = 1;
                Pre[Next] = Now;
                if( Next == End )
                {
                    Find = true;
                    GetCount( Next );
                    return ;
                }
                Path.push ( Next );
            }
        }
    }
}
int main()
{
    cin >> T;
    while( T-- )
    {
        cin >> Start >> End;
        if( Start == End )
        {
            cout<<0<<endl;
            continue;
        }
        number = 0;
        Find = false;
        bfs();
        if( Find )
            cout<< number <<endl;
        else
            cout<< "Impossible" << endl;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值