poj1326(bfs)
这个题意是计算出从输入的第一个数开始到第二个数结束之间的素数(每一个素数都只改变一个数字),每改变一次就花掉1pound,输出总共要花的pounds。使最少的步骤成为第二个数据。要解决的主要问题就在于怎样确定那个要改变的素数与上一个数只有一个数字不同。
1 #include <iostream> 2 #include <queue> 3 #include <cmath> 4 #include <cstring> 5 using namespace std; 6 int visited[10000]; 7 queue <int> vi; 8 int q; 9 int step[10000]; 10 bool isprim(int n)//判断是否素数; 11 { 12 for (int i = 2; i <= sqrt(n*1.0); ++i) 13 { 14 if (n % i == 0) 15 return false; 16 } 17 return true; 18 } 19 int main() 20 { 21 int t,m,n,first,next,temp; 22 cin>>t; 23 while(t--) 24 { 25 memset(visited,0,sizeof(visited)); 26 memset(step,0,sizeof(step)); 27 cin>>m>>n; 28 vi.push(m); 29 step[m]=0; 30 visited[m]=1; 31 while(!vi.empty()) 32 { 33 first = vi.front(); 34 vi.pop(); 35 // if(first == n)break;(由于多了这一条,错了很久,头疼死了) 36 for(int i = 0; i <= 9; i ++)//对数据变动,由1到9循环; 37 { 38 for(int j = 1; j <=4; j ++)//个十百千位分别各自变动; 39 { 40 if(j == 1 && i!= 0)//千位不能为0 41 { 42 next = i*1000+(first -first/1000*1000);//这个式子我想不出来是怎么写出来的 43 if(isprim(next) && !visited[next])//判断千位变动是否为素数,是否出现过,如果是素数且未出现过,加入队列,标记;以下同这一样; 44 { 45 vi.push(next); 46 visited[next]=1; 47 step[next]=step[first]+1; 48 } 49 } 50 if(j == 2) 51 { 52 next = first/1000*1000+i*100+(first - first/100*100); 53 if(isprim(next) && !visited[next]) 54 { 55 vi.push(next); 56 visited[next]=1; 57 step[next]=step[first]+1; 58 } 59 } 60 if(j ==3) 61 { 62 next = first/100*100+i*10+(first-first/10*10); 63 if(isprim(next) && !visited[next]) 64 { 65 vi.push(next); 66 visited[next]=1; 67 step[next]=step[first]+1; 68 } 69 } 70 if(j == 4) 71 { 72 next = first/10*10+i; 73 if(isprim(next)&& !visited[next]) 74 { 75 vi.push(next); 76 visited[next]=1; 77 step[next]=step[first]+1; 78 } 79 } 80 } 81 } 82 if(visited[n])//判断n出现时在第几步;即访问了的时候(visited[n]==1) 83 temp = step[n]; 84 } 85 cout<<temp<<endl; 86 } 87 }