本文主要是介绍POJ3126 Prime Path【数论】【BFS】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
题目链接:
http://poj.org/problem?id=3126
题目大意:
给你两个有四位数字的素数 A、B,问:每次只改变一个数字,且改变前后的数都是
素数,那么从 A 变到 B,最少需要多少次。
解题思路:
用 BFS 来做。判断素数用筛法求素数打表预处理一下,不过注意 1000 以下的数要
当非素数看待。
每次改变一位数字,并且如果改变后的数仍为素数的话入队,并用 cnt[] 来记录步数。
直到得到目标数的时候,返回结果。
AC代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int MAXN = 10100;bool Prime[MAXN];void IsPrime()
{Prime[0] = Prime[1] = false;for(int i = 2; i < MAXN; ++i)Prime[i] = true;for(int i = 2; i < MAXN; ++i){if(Prime[i]){for(int j = i+i; j < MAXN; j+=i)Prime[j] = false;}}for(int i = 2; i < 1000; ++i)Prime[i] = false;
}
bool vis[MAXN];
int t[5],cnt[MAXN];int Bfs(int S,int T)
{queue<int> q;memset(vis,false,sizeof(vis));memset(cnt,0,sizeof(cnt));q.push(S);vis[S] = true;while(!q.empty()){int v = q.front();q.pop();//存取各个位上数字t[0] = v/1000;t[1] = v/100%10;t[2] = v/10%10;t[3] = v%10; t[0]=v/1000;// printf("%d %d %d %d\n",t[0],t[1],t[2],t[3]);for(int j = 0; j < 4; ++j){int temp = t[j]; //记录第 j 个数字for(int i = 0; i <= 9; ++i) //将 t[j] 改变为 i{if(i != temp){t[j] = i;int vtemp = t[0]*1000 + t[1]*100 + t[2]*10 + t[3];if(!vis[vtemp] && Prime[vtemp]){cnt[vtemp] = cnt[v] + 1;vis[vtemp] = true;q.push(vtemp);}if(vtemp == T)return cnt[vtemp];}}t[j] = temp; //变回原本数字,继续改变另外数字}if(v == T)return cnt[v];}return -1;
}int main()
{int T,A,B;IsPrime();scanf("%d",&T);while(T--){scanf("%d%d",&A,&B);int Ans = Bfs(A,B);if(Ans == -1)printf("Impossible\n");elseprintf("%d\n",Ans);}return 0;
}
这篇关于POJ3126 Prime Path【数论】【BFS】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!