题目衔接:http://poj.org/problem?id=3126
题目大意:对一个4位数进行变换,每次只能变一个数字,求变化到另一数字的最小变换数,注意第一位不能为0,用宽度优先搜索,第一次找到该数字时,即为最小变换次数
代码如下:
#include <iostream>
#include <queue>
#include <cstring>
using namespace std;
#define maxn 10000
typedef struct data{
int num;
int pound;
}data;
int first,second;
bool visited[maxn];
bool is_prime(int num)
{
for(int i=2;i<num/2;i++)
if(num%i == 0)
return false;
return true;
}
int get_next_prime(int num)
{
for(int i=0;i<=9;i++){
int m = (num/10)*10 + i; //改变个位
if(!visited[m] && is_prime(m)) //注意2个条件的顺序,可以减少计算量
return m;
int n = (num/100)*100+num%10+i*10; //改变十位
if(!visited[n] && is_prime(n))
return n;
int p = (num/1000)*1000+i*100+((num%100)/10)*10+num%10; //改变百位
if(!visited[p] && is_prime(p))
return p;
if(i != 0){ //首位不能为0
int q = i*1000+((num%1000)/100)*100+((num%100)/10)*10+num%10; //改变千位
if(!visited[q] && is_prime(q))
return q;
}
}
return -1; //如果没有结果,返回-1
}
int answer_bfs()
{
queue<data> store;
data first_item;
first_item.num = first;
first_item.pound = 0;
store.push(first_item);
visited[first]=true;
if(first == second)
return 0;
while(!store.empty()){
data temp_data = store.front();
store.pop();
int number = temp_data.num ;
int prime = get_next_prime(number);
while(prime != -1){
visited[prime] = true;
data temp;
temp.num = prime;
temp.pound = temp_data.pound+1;
if(prime == second) //找到结果,直接返回
return temp.pound;
store.push(temp);
prime = get_next_prime(number);
}
}
return -1;
}
int main()
{
int cases;
cin>>cases;
while(cases--){
memset(visited,false,sizeof(visited)); //记住初始化
cin>>first>>second;
int answer = answer_bfs();
if(answer == -1)
printf("Impossible\n");
else
printf("%d\n",answer);
}
return 0;
}