您的位置:首页 > 其它

POJ 3126 Prime Path

2015-07-29 09:52 537 查看
给定两个四位素数a b,要求把a变换到b

变换的过程要保证 每次变换出来的数都是一个 四位素数,而且当前这步的变换所得的素数 与 前一步得到的素数 只能有一个位不同,而且每步得到的素数都不能重复。

求从a到b最少需要的变换次数。无法变换则输出Impossible

输入:

第一行 是一个数T 表示下面有T个测试数据

下面T行 每行两个数a b

解题思路:每次变换一次,个十百千,四个位置上的数每个从0-9循环一边一共需要4 * 10 = 40次循环 剪枝之后就没多少了 所以直接暴力BFS能过

下面是代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <cstdlib>
#include <cmath>
#include <cctype>
#define N 10000
#define MAXV 10000
using namespace std;
bool Prime[11000];//Prime[i] = false证明 i 是素数
void MakePrime()//对素数打表
{
int i, j;
for(i = 1000; i <= N; i++) {
for(j = 2; j < i; j++) {
if(i % j == 0) {
Prime[i] = false;
break;
}
}
if(j == i) Prime[i] = true;
}
}
void BFS(int s, int e)
{
bool maps
; //用来记录此数是不是已经变换过
int step
, d[4], temp, e_temp, i, j; //d代表个十百千四个位置,step[i]用来储存变换为 i 时一共变换了几次
queue<int>q;
memset(step, 0, sizeof(step));
memset(maps, false, sizeof(maps));
q.push(s);
maps[s] = true;
while(!q.empty()) {
s = q.front();
q.pop();
d[0] = s % 10;//个
d[1] = s / 10 % 10;//十
d[2] = s / 100 % 10;//百
d[3] = s / 1000;//千
for(i = 0; i < 4; i++) { //四个位置
temp = d[i]; //原本在此位置的数字 先用temp保存 因为后面如果改变的是其他位置这个位置不变
for(j = 0; j < 10; j++) { //0-9十个数
if(temp != j) { //自己不需要再次判断
d[i] = j;
e_temp = d[0] + d[1] * 10 + d[2] * 100 + d[3] * 1000;
if(!maps[e_temp] && Prime[e_temp]) { //判断这个数有没有判断过,是不是质数
maps[e_temp] = true;
step[e_temp] = step[s] + 1;
q.push(e_temp);
}
if(e_temp == e) { //查找到 输出转换次数
printf("%d\n", step[e_temp]);
return;
}
}
d[i] = temp;
}
}
if(s == e) {
printf("%d\n", step[s]);
return;
}
}
//所有的数都变换过 无法得到结果
printf("Impossible\n");
}
int main()
{
MakePrime();
int start, end, T;
scanf("%d", &T);
while(T--) {
scanf("%d %d", &start, &end);
BFS(start, end);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: