现给定两个 四位素数 a,ba,b。 你可以执行多次下面的操作:
修改数字 aa 的某一位, 使其成为另一个 四位素数。
例如,1033→17331033→1733,其中 10331033 与 17331733 均为素数。
问至少多少次变换后能从 aa 得到 bb ? 或回答不可能。
数据规模
- 多组数据 1≤T≤1001≤T≤100
输入格式
第一行一个数字 TT,表示接下来将会有 TT 组数据。
接下来包含 TT 行,每行包含用空格分开的两个 四位素数 a,ba,b。
输出格式
输出 TT 行,如果可以,输出最小变换次数。反之输出 −1−1。
样例输入
2
1033 1033
1033 8779
样例输出
0
5
说明
1033→1733→3733→3739→3779→87791033→1733→3733→3739→3779→8779
tips: you only operate 88 times if possible.
这一题可以使用bfs,首先将四位数的素数提取出来,用map存储,将其看成一个无向图,且边权为1,然后使用bfs,在个位,十位,百位,千位,改变一个位数的数,判断这个数是否已经进队并且判断是否是素数,然后如果都合格,就入队,然后继续bfs,直到找到第一个答案,因为bfs第一个找到的答案一定是最优解,直接输出。
一开始我还在想贪心,然后实在贪心不出来,就去看题解,经过sls大佬,我明白了这个可以遍历找到答案的题目可以使用bfs。
代码如下:
#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<math.h>
#include<set>
#include<numeric>
#include<string>
#include<string.h>
#include<iterator>
#include<map>
#include<unordered_map>
#include<stack>
#include<list>
#include<queue>
#include<iomanip>
typedef long long ll;
typedef pair<ll, ll>PII;
const int N = 1e5 + 50, MOD = 1e8 - 7;
bool prime(int num)
{
if (num == 2 || num == 3)
return true;
if (num % 6 != 1 && num % 6 != 5)
return false;
int temp;
temp = int(sqrt(float(num)));
for (int i = 5; i <= temp; i += 6)
{
if (num % i == 0 || num % (i + 2) == 0)
return false;
}
return true;
}
map<ll, ll>mp;
ll st[N];
ll arr[N];
void bfs(ll x,ll y)
{
map<ll, ll>mymp;
memset(st, 0, sizeof(st));
queue<ll>q;
q.push(x);
mymp[x] = 0;
st[x] = 1;
while (q.size())
{
auto u = q.front(); q.pop();
/*cout << "u :" << u << "mp[u]" << mymp[u] << "\n";*/
if (u == y)
{
cout << mymp[u] << "\n";
return;
}
ll a = u % 10;
ll b = (u / 10) % 10;
ll c = (u / 100) % 10;
ll d = u / 1000;
for (int i = 1; i <= 9; i++)
{
if (i == a)continue;
ll num = i + 10 * b + 100 * c + 1000 * d;
if (mp[num] && !st[num])q.push(num), mymp[num] = mymp[u] + 1,st[num] = 1;
}
for (int i = 0; i <= 9; i++)
{
if (i == b)continue;
ll num = a + 10 * i + 100 * c + 1000 * d;
if (mp[num] && !st[num])q.push(num), mymp[num] = mymp[u] + 1, st[num] = 1;
}
for (int i = 0; i <= 9; i++)
{
if (i == c)continue;
ll num = a + 10 * b + 100 * i + 1000 * d;
if (mp[num] && !st[num])q.push(num), mymp[num] = mymp[u] + 1, st[num] = 1;
}
for (int i = 0; i <= 9; i++)
{
if (i == d)continue;
ll num = a + 10 * b + 100 * c + 1000 * i;
if (mp[num] && !st[num])q.push(num), mymp[num] = mymp[u] + 1, st[num] = 1;
}
}
cout << -1 << "\n";
}
void work()
{
ll a, b;
cin >> a >> b;
bfs(a, b);
}
int main()
{
for (int i = 1000; i <= 9999; i++)
{
if (prime(i))mp[i] = 1;
}
/*for (int i = 1000; i <= 9999; i++)
{
if (mp[i])cout << i << "\n";
}*/
ll t;
cin >> t;
while (t--)
{
work();
}
return 0;
}