题意:给你一个四位数(1000~10000),每次改变使他变为一个素数,问要改变几次才能到所给出的另一个素数值,同时要保证改变次数最小
思路: 先素数打表,然后再bfs搜索(这样便于求出最小次数) 。
bfs搜索可以将当前数字进行改变然后求所得,还有一种办法 看到题解有种比较暴力的匹配(从1000~10000遍历如果有一个位数则可以进行改变,这样相对当前数字改变代码简洁多)
完整代码:
#include<cstdio> #include<cstring> #include<queue> using namespace std; const int maxn=10000+7; int isprime[maxn]; //素数表 int vis[maxn]; //标记数组 int step[maxn]; //记录步数 int n,m; void prime() { memset(isprime,0,sizeof(isprime)); for(int i=2;i*i<maxn;i++){ if(!isprime[i]){ for(int j=i*i;j<maxn;j+=i) isprime[j]=1; } } return ; } bool change(int x,int y) //将x,y分为 千位 百位 十位 个位 { int x1,x2,x3,x4; int y1,y2,y3,y4; x1=x/1000; y1=y/1000; x2=(x%1000)/100; y2=(y%1000)/100; x4=x%10; y4=y%10; x3=(x%100)/10; y3=(y%100)/10; int num=0; if(x1==y1) num++; if(x2==y2) num++; if(x3==y3) num++; if(x4==y4) num++; if(num==3) return true; //如果有三位相同 则仅有一位不同 else return false; } int bfs(int n,int m) { memset(vis,0,sizeof(vis)); memset(step,-1,sizeof(step)); queue<int>q; while(!q.empty()) q.pop(); q.push(n); vis[n]=1; step[n]=0; while(!q.empty()){ int cur=q.front(); if(cur==m) return 1; q.pop(); for(int i=1000;i<maxn;i++){//这样就不用改变位数,直接匹配了 if(!vis[i]&&!isprime[i]&&change(cur,i)&&step[i]==-1){ q.push(i); vis[i]=1; step[i]=step[cur]+1; } } } return 0; } int main() { prime(); int t; scanf("%d",&t); while(t--){ scanf("%d %d",&n,&m); if(bfs(n,m)) printf("%d ",step[m]); else printf("Impossible "); } return 0; }