POJ-3126 Prime Path 【BFS+剪枝】
阿新 • • 發佈:2018-11-01
題目:給定兩個四位數n,m,每次改變n中的一位數並且保證改變後的n仍然是素數,問n最少要經過多少次改變才能變成m。若不論經過多少次改變都不能變成m那麼輸出Impossible。
題解:BFS,列舉改變的數。
注意:1.最後一位數一定不能是偶數,中間兩位數可以是0~9的任意值,第一位數一定不能是0。
2.如果一個改變的數在之前就已經得到過了,就不用再次變回它了,所以用vis陣列標記一下已經改變過的數。
AC程式碼:
#include <iostream> #include <algorithm> #include <cstdio> #include <cstring> #include <string> #include <cmath> #include <queue> #include <stack> #include <vector> #include <map> #include <set> using namespace std; #define io ios::sync_with_stdio(0),cin.tie(0) #define ms(arr) memset(arr,0,sizeof(arr)) #define inf 0x3f3f3f typedef long long ll; const int mod=1e9+7; const int maxn=1e5+7; int t,n,m,vis[maxn]; struct node { int a,b,c,d; int step; node(){} node(int _a,int _b,int _c,int _d):a(_a),b(_b),c(_c),d(_d){} }; bool isPrime(int x)//判斷x是否為素數 { for(int i=2;i*i<=x;i++) { if(x%i==0) return false; } return true; } bool isequal(node x,node y)//判斷x,y是否相等 { if(x.a==y.a&&x.b==y.b&&x.c==y.c&&x.d==y.d) return true; return false; } queue <node> q; void bfs() { while(!q.empty()) { q.pop(); } vis[n]=1; node tmp; tmp.a=n%10;n/=10; tmp.b=n%10;n/=10; tmp.c=n%10;n/=10; tmp.d=n; tmp.step=0; node ans; ans.a=m%10;m/=10; ans.b=m%10;m/=10; ans.c=m%10;m/=10; ans.d=m; q.push(tmp); while(!q.empty()) { node now=q.front(); q.pop(); if(isequal(now,ans))//若now與ans相等,輸出now改變的次數 { cout<<now.step<<endl; return ; } for(int i=1;i<=9;i+=2) { if(now.a!=i) { tmp=node(i,now.b,now.c,now.d); tmp.step=now.step+1; if(isPrime(tmp.a+tmp.b*10+tmp.c*100+tmp.d*1000)&&vis[tmp.a+tmp.b*10+tmp.c*100+tmp.d*1000]==0) { q.push(tmp); vis[tmp.a+tmp.b*10+tmp.c*100+tmp.d*1000]=1; } } } for(int i=0;i<=9;i++) { if(now.b!=i) { tmp=node(now.a,i,now.c,now.d); tmp.step=now.step+1; if(isPrime(tmp.a+tmp.b*10+tmp.c*100+tmp.d*1000)&&vis[tmp.a+tmp.b*10+tmp.c*100+tmp.d*1000]==0) { q.push(tmp); vis[tmp.a+tmp.b*10+tmp.c*100+tmp.d*1000]=1; } } } for(int i=0;i<=9;i++) { if(now.c!=i) { tmp=node(now.a,now.b,i,now.d); tmp.step=now.step+1; if(isPrime(tmp.a+tmp.b*10+tmp.c*100+tmp.d*1000)&&vis[tmp.a+tmp.b*10+tmp.c*100+tmp.d*1000]==0) { q.push(tmp); vis[tmp.a+tmp.b*10+tmp.c*100+tmp.d*1000]=1; } } } for(int i=1;i<=9;i++) { if(now.d!=i) { tmp=node(now.a,now.b,now.c,i); tmp.step=now.step+1; if(isPrime(tmp.a+tmp.b*10+tmp.c*100+tmp.d*1000)&&vis[tmp.a+tmp.b*10+tmp.c*100+tmp.d*1000]==0) { q.push(tmp); vis[tmp.a+tmp.b*10+tmp.c*100+tmp.d*1000]=1; } } } } cout<<"Impossible"<<endl; return ; } int main() { io; cin>>t; while(t--) { cin>>n>>m; ms(vis); bfs(); } return 0; }