Problem Discription
In this problem, you are given an integer number . You can transform any integer number to another integer number by adding to . This is an integer number which is a prime factor of (please note that 1 and are not being considered as a factor of ). Now, your task is to find the minimum number of transformations required to transform to another integer number .
Input
Input starts with an integer , denoting the number of test cases.
Each case contains two integers: and .
Output
For each case, print the case number and the minimum number of transformations needed. If it's impossible, then print .
Sample Input
2
6 12
6 13
Sample Output
Case 1: 2
Case 2: -1
代码
#include<iostream>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
struct node{
int x,step;
friend bool operator< (node a,node b){
return a.step>b.step;
}
};
bool cmp(int a,int b){
return a>b;
}
int prime[200]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997};
int factor[200];
bool vis[1005];
void BFS(int s,int t){
priority_queue<node> q;
node t1,t2;
memset(vis,0,sizeof(vis));
int ans=-1;
int i;
t1.x=s,t1.step=0;
q.push(t1);
vis[t1.x]=1;
while(!q.empty()){
t1=q.top();
q.pop();
if(t1.x==t){
ans=t1.step;
break;
}
int j,k;
for(j=0,k=0;j<168&&t1.x>prime[j];j++)
if(t1.x%prime[j]==0) factor[k++]=prime[j];
sort(factor,factor+k,cmp);
for(i=0;i<k;i++){
t2.x=t1.x+factor[i];
t2.step=t1.step;
if(t2.x>t||vis[t2.x]) continue;
else t2.step++;
q.push(t2);
vis[t2.x]=1;
}
}
cout<<ans<<endl;
}
int main(){
int n;
cin>>n;
int i,j,k;
for(i=1;i<=n;i++){
int s,t;
cin>>s>>t;
cout<<"Case "<<i<<": ";
BFS(s,t);
}
return 0;
}
解题思路
1、题目讲了一个从A转换到B的转化规则,这里指的是通用转换规则,也就是说把s转换为t,先将s与s的素因数相加后得s',以此类推地把s'与s'的素因数相加得s'',一步一步最终转换成t,而不是一直用s的素因数来相加转换。
2、需要用vis数组来标记是否访问过,因为优先队列每次取的是step最小的,如果取出再加上素因数后得到的新数已经访问过,就没必要把这个节点放入到优先队列中,如果不这么做会超时。