首页 > 代码库 > 一天一道算法题--5.25--bfs或者最短路

一天一道算法题--5.25--bfs或者最短路

好吧 还是拖到了5.26来写本是5.25的题。。。

自我 宽恕

老样子---  感谢    微信平台: 一天一道算法题   无聊的你 也可以去关注一下

题目 链接:http://poj.org/problem?id=3126

题目 大意:  给你2个素数 问从一个素数到另一个转换的过程中  每次只允许改变一个位上的数 并且在改动过程中 保证它也是素数  最少需要多少次实现这个转换?

 

ok 其实 这题 不算难  当告诉你这是个搜索以后  只是在进行个位 十位 百位 千位 上各个数字尝试的时候 可能会有点小困难吧   反正我是遇到了---------

怎么说呢  你可以选择开一个结构体 来存储 素数和步数     我还是喜欢开2个数组 来实现  随便 个人喜好问题

我被一个 素数判断函数少个 = 号 找了好久 都没发现  最后还是大神 一眼发现 流弊。。。

这里 有人会在Bfs的时候 自己模拟队列实现 而我还是喜欢直接用 stl里的queue 不会存在 数组大小问题 也感觉更容易 

下面 贴上我的代码:

  1 #include <iostream>
  2 #include <cstring>
  3 #include <queue>
  4 using namespace std;
  5 
  6 const int num = 10010;
  7 bool vis[num];
  8 bool prime[num];
  9 int step[num];
 10 
 11 void judge( int n )
 12 {
 13     bool flag = false;
 14     for( int i = 2 ; i*i<=n ; i++ )
 15     {
 16         if( n%i == 0 )
 17         {
 18             flag = true;
 19             break;
 20         }
 21     }
 22     if( flag )
 23         prime[n] = true;//合数 就是 true
 24 }
 25 
 26 bool bfs( int st , int end )
 27 {
 28     int temp;
 29     int i;
 30     int a , b;
 31     queue<int>q;
 32     while( !q.empty() )
 33         q.pop();
 34     q.push(st);
 35     if( st==end )
 36     {
 37         return true;
 38     }
 39     while( !q.empty() )
 40     {
 41         int now = q.front();
 42         q.pop();
 43         if( now == end )
 44             return true;
 45         a = now%10; //个位上的数
 46         b = (now/10)%10;//十位上的数
 47         //枚举个位:肯定是奇数 不然不可能是素数
 48         for( i = 1 ; i<=9 ; i+=2 )
 49         {
 50             temp = (now/10)*10 + i;
 51             if( temp!=now && !vis[temp] && !prime[temp] )
 52             {
 53                 vis[temp] = true;
 54                 step[temp] = step[now] + 1;
 55                 q.push( temp );
 56             }
 57         }
 58         //枚举十位:
 59         for( i = 0 ; i<=9 ; i++ )
 60         {
 61             temp = ( now/100 )*100 + 10*i +a;
 62             if( temp!=now && !vis[temp] && !prime[temp] )
 63             {
 64                 vis[temp] = true;
 65                 step[temp] = step[now] + 1;
 66                 q.push( temp );
 67             }
 68         }
 69         //枚举百位:
 70         for( i = 0 ; i<=9 ; i++ )
 71         {
 72             temp = ( now/1000)*1000 + 100*i + 10*b + a;
 73             if( temp!=now && !vis[temp] && !prime[temp] )
 74             {
 75                 vis[temp] = true;
 76                 step[temp] = step[now] + 1;
 77                 q.push( temp );
 78             } 
 79         }
 80         //枚举千位  肯定不能以0开头
 81         for( i = 1 ; i<=9 ; i++ )
 82         {
 83             temp = now%1000 + i*1000;
 84             if( temp!=now && !vis[temp] && !prime[temp] )
 85             {
 86                 vis[temp] = true;
 87                 step[temp] = step[now] + 1;
 88                 q.push( temp );
 89             }
 90         }
 91     }
 92     return false;
 93 }
 94 
 95 int main()
 96 {
 97     int t;
 98     int st , end;
 99     memset( prime , false , sizeof(prime) );
100     for( int i = 1000 ; i<=9999 ; i++ )
101     {
102         judge(i);
103     }
104     while( ~scanf("%d",&t) )
105     {            
106         while( t-- )
107         {
108             memset( vis , false , sizeof(vis) );
109             memset( step , 0 , sizeof(step) );
110             scanf( "%d %d",&st,&end );
111             if( bfs( st , end ) )
112             {
113                 printf( "%d\n",step[end] );
114             }
115             else
116             {
117                 printf( "Impossible\n" );
118             }
119         }
120     }
121     return 0;
122 }
View Code

PS:微信上说 可以用 最短路来实现 = 我今晚看有空来 去写下试下
话说  今天的算法题 又已经出来了   看来要=到 今晚 才能写了 明天又要上那 该死的高数 还有那本来很美好的C++ 被个不好的老师教的。。。。