题意:求素数a变换到素数b的最小步数,每次只能更改一位,且更改后的数也是素数。每次输入的两个素数都是4位数。
解法一:利用埃式筛法打表,用数组记录素数,把所有素数放在一个数组中,然后在这个数组的基础上进行bfs。
解法二:打表记录每个数的素数性质,然后将a的每一位依次改变,进行bfs,前面的打表在bfs中作为一个判断条件。
解法一代码:
/*
@Filename: test.cpp
@Version: 1.0
@Author: wyl6
@Email: 17744454343@163.com
*/
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <stack>
#include <queue>
#include <algorithm>
#include <cstring>
#include <string>
#include <cmath>
#include <vector>
#include <bitset>
#include <list>
#include <sstream>
#include <set>
#include <map>
#include <functional>
using namespace std;
#define INF 0x3f3f3f3f
#define maxn 10000
typedef long long ll;
typedef pair<int,int> pa;
int p;
int prime[maxn];
bool is_prime[maxn];
bool used[maxn];
bool change(int x,int y)
{
int i = 0;
while(x != 0){
if(x%10 == y%10) i++;
x /= 10;
y /= 10;
}
if(i == 3) return true;
return false;
}
void bfs(int s,int end)
{
queue <pa> que;//first序号,second深度
que.push(pa(s,0));
memset(used,0,sizeof(used));
used[s] = true;
while(!que.empty()){
pa e = que.front(); que.pop();
for (int i = 0; i < p ; ++i){
if (change(prime[e.first],prime[i]) && !used[i]){
if(prime[i] == prime[end]){
cout << e.second+1 << endl;
return;
}
used[i] = true;
que.push(pa(i,e.second+1));
}
}
}
printf("Impossible\n");
}
int main()
{
//埃式筛法打表
p = 0;
for (int i = 0; i < maxn; ++i) is_prime[i] = true;
is_prime[0] = is_prime[1] = false;
for (int i = 2; i < maxn; ++i) {
if (is_prime[i]){
prime[p++] = i;
for (int j = 2*i; j < maxn; j += i) is_prime[j] = false;
}
}
int n;
cin >> n;
while(n--){
int a,b,s,end;
cin >> a >> b;
for (int i = 0; i < p; ++i){
if(prime[i] == a) s = i;
if(prime[i] == b) end = i;
}
if (s == end) printf("0\n");
else bfs(s,end);
}
return 0;
}
解法二代码:
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <stack>
#include <queue>
#include <algorithm>
#include <cstring>
#include <string>
#include <cmath>
#include <vector>
#include <bitset>
#include <list>
#include <sstream>
#include <set>
#include <map>
#include <functional>
using namespace std;
#define maxn 10000
typedef pair<int,int> pa;
bool is_prime[maxn];
int used[maxn];
void bfs(int s,int end)
{
queue <pa> que;//first序号,second深度
que.push(pa(s,0));
memset(used,0,sizeof(used));
used[s] = true;
while(!que.empty()){
pa e = que.front(); que.pop();
for (int i = 1; i <= 1000; i *= 10){
for (int j = 0; j < 10; ++j){
int sum = e.first%i+e.first/(i*10)*(i*10)+i*j;
if(i == 1000 && j == 0) continue;
if(sum == end){
printf("%d\n",e.second+1); return;
}
if (is_prime[sum] && !used[sum]){
used[sum] = 1;
que.push(pa(sum,e.second+1));
}
}
}
}
printf("Impossible\n");
}
int main()
{
for (int i = 0; i < maxn; ++i) is_prime[i] = true;
is_prime[0] = is_prime[1] = false;
for (int i = 2; i < maxn; ++i) {
if (is_prime[i]){
for (int j = 2*i; j < maxn; j += i) is_prime[j] = false;
}
}
int n;
scanf("%d",&n);
while(n--){
int a,b;
scanf("%d%d",&a,&b);
if (a == b) printf("0\n");
else bfs(a,b);
}
return 0;
}
p.s.
易错点一:埃式筛法时忘了考虑数组边界,越界造成runtime error
易错点二:初始化问题
易错点三:循环的上下界