POJ 3126 Prime Path bfs求最短路

来源:互联网 发布:画logo的软件 编辑:程序博客网 时间:2024/06/13 06:18

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

题意:给出两个四位数(无前导零)a和b,都是素数,规定以下变换规则:
每次只能改变数的一位,变换完的数仍要求是质数,且仍为四位数。
求最少经过几次变换,能使a变换成b,如果不能从a变成b,则输出“Impossible”。

思路:考虑将素数看作点,将能够经过变换得到的两点看作两点之间有边,建立无向图,利用邻接表存储。最后用bfs求出最短路程即可。
说起来好像挺简单然而细节特别多小错误不断,三个小时的训练赛做了一个半小时差不多快疯了。。。

这题也可以不需要显式的建图,代码会简单不少,以下是显式建图的代码。

代码:c++

#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <cmath>#include <map>#include <set>#include <queue>using namespace std;const int maxn = 10000+10;int a, b;bool primenum[maxn];bool vis[maxn];map<int, set<int> > pic;int step[maxn];int ans;//判断素数bool isprime(int u){    int sqrtu = sqrt(u);    for(int i=2; i<=sqrtu; i++)    {        if(u%i==0)        {            return false;        }    }    return true;}//素数打表void preprime(){    for(int i=1000; i<=9999; i++)    {        if(isprime(i))        {            primenum[i] = true;        }    }}//建图void drawpic(){    char s[10] = {0};    for(int i=1000; i<=9999; i++)    {        if(primenum[i])        {            sprintf(s, "%d", i);            for(int j=0; j<4; j++)            {                char ss[10] = {0};                strcpy(ss, s);                ss[j] = '0';                int minn;                sscanf(ss, "%d", &minn);                for(int k=0; k<10; k++)                {                    if(j==0&&k==0)                        continue;                    int t = minn+k*(int)round(pow(10, 3-j));                    if(primenum[t]&&i!=t)                    {                        pic[i].insert(t);                        pic[t].insert(i);                    }                }            }        }    }}//bfs求最短路bool bfs(){    ans = 0;    if(a==b)    {        return true;    }    memset(step, 0, sizeof(step));    memset(vis, 0, sizeof(vis));    queue<int> q;    q.push(a);    vis[a] = true;    while(!q.empty())    {        int t = q.front();        q.pop();        set<int>::iterator it = pic[t].begin();        for(; it!=pic[t].end(); it++)        {            if(!vis[*it])            {                q.push(*it);                vis[*it] = true;                step[*it] = step[t] + 1;                if(*it==b)                {                    ans = step[*it];                    return true;                }            }        }    }    return false;}int main(){    preprime();    drawpic();    int T;    cin >> T;    while(T--)    {        scanf("%d%d", &a, &b);        if(bfs())            printf("%d\n", ans);        else            printf("Impossible\n");    }    return 0;}
原创粉丝点击