我特么真是醉了;
题意:给你两个四位数,问你能不能从一个数搜到另一个数,每次只改变其中的一位,并且保证每次得到的这个数是素数;
如果有,给出最短路径,如果没有,输出“impossible”
AC代码:
#include <stdio.h> #include <string.h> #include <algorithm> #include <iostream> #include <queue> #include <math.h> const int dx[4]= {0,0,-1,1}; const int dy[4]= {1,-1,0,0}; using namespace std; int vis[100000],dis[100000],qq[10],ll[10],a1,ql[10],q1,q2,l1; struct node { int a; int cnt; } ss,kk,k,k1; int bfs(int x,int y) { ss.a=x; ss.cnt=0; queue<node>q; q.push(ss); while(!q.empty()) { kk=q.front(); q.pop(); int l; a1=kk.a; q1=0; while(a1) { ql[q1++]=a1%10; a1/=10; } q2=0; for(int i=0; i<q1; i++) { qq[q2++]=9-ql[i]; } l1=0; for(int i=0; i<4; i++) { if(ql[i]>=1) { if(i==3) { ll[l1++]=ql[i]-1; } else { ll[l1++]=ql[i]; } } else { ll[l1++]=0; } } for(int i=0; i<4; i++) { if(ll[i]>=1) { for(int j=1; j<=ll[i]; j++) { l=kk.a-j*pow(10,i); //printf("%d ",l); //printf("%d ",i); if(l==y) { return kk.cnt+1; } if(l>=1000&&l<=9999&&vis[l]==0&&dis[l]==1) { vis[l]=1; k1.a=l; k1.cnt=kk.cnt+1; q.push(k1); } } } } for(int i=0; i<4; i++) { for(int j=1; j<=qq[i]; j++) { l=kk.a+j*pow(10,i); //printf("%d ",l); if(l==y) { return kk.cnt+1; } if(l>=1000&&l<=9999&&vis[l]==0&&dis[l]==1) { vis[l]=1; k.a=l; k.cnt=kk.cnt+1; q.push(k); } } } } return 0; } int main() { memset(dis,0,sizeof(dis)); int i; for(i=1000; i<=9999; i++) { int k=sqrt(i); int j; for(j=2; j<=k; j++) { if(i%j==0) { break; } } if(j==k+1) { dis[i]=1; } } int a,b,n; scanf("%d",&n); while(n--) { memset(vis,0,sizeof(vis)); scanf("%d%d",&a,&b); if(a==b) { printf("0 "); } else if(dis[a]==0||dis[b]==0) { printf("Impossible "); } else { int ans=bfs(a,b); if(ans) { printf("%d ",ans); } else { printf("Impossible "); } } } return 0; }