这题求最短路 ,所有的状态转移为 9999-999, 不超过10000,最多100个test case, 最坏的时间复杂度为 10e6,绝对不会超时的。
因为求最短路,要么枚举所有 dfs路径, 要么使用 bfs ,不过我同学说求最短路一般bfs要比纯dfs快,但是bfs 会消耗更多的内存,这题内存65536kb,没有卡内存,所以直接暴力bfs。
对于每个四位数, 最多有 9 * 9 * 9 * 9 =6561 种状态转移,再加个visit数组,因为已经访问过的状态没必要在再访问一遍。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
const int TOP=1e7+10000;//+10000是为了多筛一个素数
bool e[TOP];
int p[TOP/5];
int pnum;
void prime()//O(n)筛素数,e[x]==0表示x为素数
{
e[0]=e[1]=1;pnum=0;
for(int i=2;i<TOP;i++)
{
if(e[i]==0)p[++pnum]=i;
for(int j=1;j<=pnum&&p[j]*i<TOP;j++)
{
e[p[j]*i]=1;
if(i%p[j]==0)break;
}
}
}
int vis[10000];
struct node
{
int p;
int level;
};
int pos[4] = {10,100,1000,10000};
int bfs(int st1,int en)
{
if(st1==en)return 0;
queue<node> qu;
node st;
st.p = st1;
st.level=0;
vis[st.p] =1;
qu.push(st);
node f;
node tmp;
int flag=0;
while(!qu.empty())
{
f = qu.front();
qu.pop();
if(f.p == en)
{
flag=1;
break;
}
//cout<<f.p<<endl;
tmp.level = f.level + 1;
for(int i=0;i<4;i++)
{
int base = (f.p - f.p%pos[i]) + f.p%(pos[i]/10);
for(int j=0;j<=9;j++)
{
int now = base + pos[i]/10*j;
// cout<<base<<" "<<now<<endl;
if(vis[now]==0&&now >=1000&&now<10000&&e[now]==0)
{
vis[now] =1;
tmp.p = now;
qu.push(tmp);
}
}
}
}
if(flag==1)
return f.level;
else return -1;
}
int main()
{
ios::sync_with_stdio(false);
prime();
int m,n;
int t;
cin>>t;
while(t--)
{
cin>>m>>n;
memset(vis,0,sizeof(vis));
cout<<bfs(m,n)<<endl;
}
return 0;
}