poj 3126 prime path 简单广搜
http://poj.org/problem?id=3126
题意:给你两个四位数a,b,从a开始 每次只能改变上一次数的其中一位,问至少需要几步才能得到b
分析:求最小路 典型的广搜 表面上是 40入口的bfs 但是除去有的数不是素数 入口数远小于40
可以写一个 判断一个数是否为素数的函数 , 每次去 调用 判断一个数是否要进队列
也可以 事先打一个素数表 这样会快点
注意:output :either with a number stating the minimal cost or containing the word Impossible
用c++才交对的 g++ not ok i am confused
1 #include <algorithm> 2 #include <iostream> 3 #include <sstream> 4 #include <cstdlib> 5 #include <cstring> 6 #include <cstdio> 7 #include <string> 8 #include <bitset> 9 #include <vector> 10 #include <queue> 11 #include <stack> 12 #include <cmath> 13 #include <list> 14 #include <map> 15 #include <set> 16 using namespace std; 17 /*10^8-----1s*/ 18 /***************************************/ 19 typedef vector<int> VI; 20 typedef vector<char> VC; 21 typedef vector<string> VS; 22 typedef set<int> SI; 23 typedef set<string> SS; 24 typedef map<int ,int> MII; 25 typedef map<string,int> MSI; 26 typedef pair<int,int> PII; 27 typedef vector<PII> VII; 28 typedef vector<VI > VVI; 29 /***************************************/ 30 #define min(a,b) (a>b?b:a) 31 #define max(a,b) (a>b?a:b) 32 33 #define clr(a,b) memset(a,b,sizeof(a)) 34 #define all(x) (x).begin(), (x).end() 35 #define sz(x) ((int)(x).size()) 36 #define ll long long 37 #define int64 __int64 38 #define pb push_back 39 #define mp make_pair 40 #define LL(x) ((x)<<1) 41 #define RR(x) ((x)<<1|1) 42 #define ri(x) scanf("%d",&x) 43 #define rii(x,y) scanf("%d%d",&x,&y) 44 #define rd(x) scanf("%lf",&x) 45 #define rdd(x,y) scanf("%lf%lf",&x,&y) 46 #define rs(x) scanf("%s",x) 47 #define pi(x) printf("%d",x) 48 #define pin(x) printf("%d\n",x) 49 #define ps(x) printf("%s",x) 50 #define pn() printf("\n") 51 #define sqr(x) ((x)*(x)) 52 #define rep(i,a,b) for(int i=(a);i<(b);i++) 53 #define repu(i,a,b) for(int i=(a);i<=(b);i++) 54 #define repd(i,a,b) for(int i=(a);i>=(b);i--) 55 #define repc(i,a,c) for(int i=(a);(c);i++) 56 /***************************************/ 57 const int INF = 0x7f7f7f7f; 58 const double eps = 1e-8; 59 const double PIE=acos(-1.0); 60 const int dx[]= {0,-1,0,1}; 61 const int dy[]= {1,0,-1,0}; 62 const int fx[]= {-1,-1,-1,0,0,1,1,1}; 63 const int fy[]= {-1,0,1,-1,1,-1,0,1}; 64 /***************************************/ 65 void openfile() 66 { 67 freopen("data.in","rb",stdin); 68 freopen("data.out","wb",stdout); 69 } 70 /**********************The End OF The Template*****************/ 71 72 int primes[10004]; 73 int visit[10004];//标记 同时 记录转换的次数 74 int a,b; 75 int w[5]; 76 int flag; 77 78 79 /*打表 筛选法求素数(2是最小的素数)*/ 80 void isprime() 81 { 82 int i,j; 83 primes[0]=0;//等于0表示非素数 84 primes[1]=0; 85 for(i=2; i<=10002; i++) 86 primes[i]=1; 87 for(i=2; i<=10002; i++) 88 { 89 if(primes[i]) 90 { 91 for(j=i+i; j<=10002; j+=i) 92 primes[j]=0; 93 } 94 } 95 } 96 97 /*广搜找最小需要的转换次数*/ 98 int bfs(int x) 99 { 100 int xx,k,t,i,j,l; 101 queue<int >q; 102 q.push(x); 103 flag=0; 104 while(!q.empty()) 105 { 106 xx=q.front(); 107 q.pop(); 108 if(xx==b) 109 { 110 flag=1; 111 return visit[xx]; 112 } 113 w[1]=xx%10; 114 w[2]=(xx/10)%10; 115 w[3]=(xx/100)%10; 116 w[4]=xx/1000; 117 118 for(i=1; i<=4; i++) // 1 个 2 十 119 for(j=0; j<10; j++) 120 { 121 if(i==4&&j==0)//最高位不能为0 122 continue; 123 if(i==1&&j%2==0)//个位为偶数跳过 124 continue; 125 k=0; 126 t=w[i]; 127 w[i]=j; 128 for(l=4; l>0; l--) 129 { 130 k=k*10+w[l]; 131 } 132 w[i]=t; 133 134 if(primes[k]&&!visit[k]) 135 { 136 visit[k]=visit[xx]+1; 137 q.push(k); 138 } 139 140 } 141 } 142 } 143 144 145 146 int main() 147 { 148 int t; 149 isprime(); 150 scanf("%d",&t); 151 while(t--) 152 { 153 memset(visit,0,sizeof(visit)); 154 scanf("%d %d",&a,&b); 155 visit[a]=1; 156 int m=bfs(a); 157 if(flag) 158 printf("%d\n",m-1); 159 else 160 printf("Impossible\n"); 161 } 162 return 0; 163 }