题意:更改四位数的门牌号(素数),每次只能改一个数字,问最少多少次能改到目标数字。
思路:打表出四位的所有素数,然后建图,只有一个位数的数字不同的连边,跑最短路,,,
#include<iostream> #include<stdio.h> #include<queue> #include<string.h> const int N=10000; const int inf=0x3fffffff; using namespace std; int link[N],prim[N],dis[N],vis[N]; struct edge { int st,ed,next; }e[N*10]; int head[N],num; void addedge(int x,int y) { e[num].st=x;e[num].ed=y;e[num].next=head[x];head[x]=num++; e[num].st=y;e[num].ed=x;e[num].next=head[y];head[y]=num++; } bool judge(int x,int y) { int sum=0; while(x) { if(x%10!=y%10) sum++; x/=10;y/=10; } if(sum==1) return true; return false; } int spfa(int s,int ed) { queue<int>Q; int i,v,u; for(i=1000;i<=9999;i++) { vis[i]=0;dis[i]=inf; } dis[s]=0;vis[s]=1; Q.push(s); while(!Q.empty()) { u=Q.front(); Q.pop(); vis[u]=0; if(u==ed)break; for(i=head[u];i!=-1;i=e[i].next) { v=e[i].ed; if(dis[v]>dis[u]+1) { dis[v]=dis[u]+1; if(vis[v]==0) { Q.push(v); vis[v]=1; } } } } return dis[ed]; } int main() { int i,j,k,t,a,b; k=0; for(i=2;i<N;i++) { if(link[i]==1)continue; for(j=i+i;j<N;j+=i) link[j]=1; if(i>999) prim[k++]=i; } memset(head,-1,sizeof(head)); num=0; for(i=0;i<k;i++) { for(j=i+1;j<k;j++) if(judge(prim[i],prim[j])) addedge(prim[i],prim[j]); } scanf("%d",&t); while(t--) { scanf("%d%d",&a,&b); printf("%d\n",spfa(a,b)); } return 0; }