LightOJ 1141 Number Transformation (BFS)

Problem Discription

In this problem, you are given an integer number s . You can transform any integer number A to another integer number B by adding x to A. This x is an integer number which is a prime factor of A (please note that 1 and A are not being considered as a factor of A). Now, your task is to find the minimum number of transformations required to transform s to another integer number t.

Input

Input starts with an integer T(\leq 500), denoting the number of test cases.

Each case contains two integers: s(1\leq s \leq 100) and t(1\leq t \leq 1000).

Output

For each case, print the case number and the minimum number of transformations needed. If it's impossible, then print -1.

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最小的,如果取出再加上素因数后得到的新数已经访问过,就没必要把这个节点放入到优先队列中,如果不这么做会超时。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值