题目链接
题目大意,给你两个素数,一次只能改变一位,问多少次能改变完成,不能则输出impossible
这道题,一开始拿到手之后,并不知道怎么做,联想一下最短路径想到BFS,但是感觉BFS没有办法解决,便没有尝试,比赛完之后,看了别人的代码竟然真的是BFS,然后尝试着自己写了写,结果连样例都没过去,原因是没有及时进行位数的还原(代码中会有体现),一开始写的时候还忘了标记使用(傻得不谈了),最后来一句,BFS大法好。
下面给出AC代码:
#include <iostream>
#include <cstdio>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 10000+10;
bool table[maxn],used[maxn];
void prime_table()
{
memset(table,0,sizeof(table));
int m=(int)sqrt(maxn+0.5);
for(int i=2;i<=m;i++)
{
if(!table[i])
for(int j=i*i;j<=maxn;j+=i)
table[j]=true;
}
}
struct node
{
int rep;
int step;
node() {}
node(int a,int b):rep(a),step(b) {}
};
int BFS(int str,int ed)
{
memset(used,0,sizeof(used));
queue<node> que;
que.push(node(str,0));
used[str]=true;//标记使用
while(!que.empty())
{
node p=que.front(); que.pop();
if(p.rep==ed) return p.step;
int sut=p.rep,t[5];
t[1]=sut/1000,t[2]=(sut/100)%10,t[3]=(sut/10)%10,t[4]=sut%10;
for(int i=1;i<=4;i++)
{
int tmp=t[i];//注意位数改变完之后一定要及时还原,否则会影响后续的使用
for(int j=0;j<=9;j++)
{
if(j==0&&i==1) continue;//没有前导0
t[i]=j;
int st=t[1]*1000+t[2]*100+t[3]*10+t[4];
if(!table[st]&&!used[st])
{
que.push(node(st,p.step+1));
used[st]=true;
}
}
t[i]=tmp;//位数还原
}
}
return -1;
}
int main()
{
prime_table();
int T; scanf("%d",&T);
while(T--)
{
int str,ed; scanf("%d %d",&str,&ed);
int cnt=BFS(str,ed);
if(cnt!=-1) printf("%d\n",cnt);
else printf("Impossible\n");
}
return 0;
}