POJ-3126 题解
Prime Path
题目大意
有一个四位的素数s,每次改变一位,变成另外一个素数t
要求每次改变后的数还是素数
最少需要改变几次
Time: 1000 ms
Memory: 65536 kB
解题思路及分析
素数筛 先筛出1e5以内的素数
然后bfs搜索,搜索改变任意一位后的素数
AC代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
const int N = 1e5 + 5;
bool isPrime[N];
bool vis[N];
vector<int> prime;
void getPrime()
{
memset(isPrime, 1, sizeof(isPrime));
for (int i = 2; i < N; i++)
{
if (isPrime[i])
{
prime.push_back(i);
}
for (int j = 0; j < prime.size() && i * prime[j] < N; j++)
{
isPrime[i * prime[j]] = false;
if (i % prime[j] == 0)
{
break;
}
}
}
}
int bfs(int s, int t)
{
queue<int> q, co;
q.push(s);
co.push(0);
vis[s] = 1;
while (!q.empty())
{
int x = q.front();
int cost = co.front();
q.pop();
co.pop();
if (x == t)
{
return cost;
}
int a = x / 1000;
int b = (x / 100) % 10;
int c = (x / 10) % 10;
int d = x % 10;
for (int i = 1; i < 10; i++)
{
int xx = i * 1000 + b * 100 + c * 10 + d;
if (isPrime[xx] && !vis[xx])
{
q.push(xx);
co.push(cost + 1);
vis[xx] = 1;
}
}
for (int i = 0; i < 10; i++)
{
int xx = a * 1000 + i * 100 + c * 10 + d;
if (isPrime[xx] && !vis[xx])
{
q.push(xx);
co.push(cost + 1);
vis[xx] = 1;
}
}
for (int i = 0; i < 10; i++)
{
int xx = a * 1000 + b * 100 + i * 10 + d;
if (isPrime[xx] && !vis[xx])
{
q.push(xx);
co.push(cost + 1);
vis[xx] = 1;
}
}
for (int i = 0; i < 10; i++)
{
int xx = a * 1000 + b * 100 + c * 10 + i;
if (isPrime[xx] && !vis[xx])
{
q.push(xx);
co.push(cost + 1);
vis[xx] = 1;
}
}
}
return -1;
}
int main()
{
getPrime();
int n, s, t;
scanf("%d", &n);
while (n--)
{
memset(vis, 0, sizeof(vis));
scanf("%d%d", &s, &t);
int ans = bfs(s, t);
if (~ans)
{
printf("%d\n", ans);
}
else
{
printf("Impossible\n");
}
}
return 0;
}