Time Limit: 2 second(s) | Memory Limit: 32 MB |
In this problem, you are given an integer number s.You can transform any integer number A to another integer number Bby adding x to A. This x is an integer number which is aprime factor of A (please note that 1 and A are not beingconsidered as a factor of A). Now, your task is to find the minimumnumber of transformations required to transform s to another integernumber t.
Input
Input starts with an integer T (≤ 500),denoting the number of test cases.
Each case contains two integers: s (1 ≤ s ≤100) and t (1 ≤ t ≤ 1000).
Output
For each case, print the case number and the minimum numberof transformations needed. If it's impossible, then print -1.
Sample Input | Output for Sample Input |
2 6 12 6 13 | Case 1: 2 Case 2: -1 |
题意:给你一个数s,t,让这个s加上一个他的质因子之后形成一个新的数,再让这个数加上他的质因子,以此类推,问多少次可以得到t。
思路:两种算法,一是bfs,另一个是最短路(已知起点和终点s,t);
下面附上代码:
第一个为bfs:
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
#define N 1100
using namespace std;
int k=0,a,b;
int pre[N],dis[N];
const int INF=0x3f3f3f3f;
void prime()
{
memset(pre,0,sizeof(pre));
for(int i=2;i*i<N;i++)
{
if(pre[i]==0)
for(int j=i*2;j<N;j+=i)
pre[j]=1;
}
}
void bfs(int a,int b)
{
queue<int> que;
memset(dis,0x3f,sizeof(dis));
que.push(a);
dis[a]=0;
while(!que.empty())
{
int v=que.front();
que.pop();
if(v==b) return;
for(int i=2;i<v;i++)
{
if(v%i==0&&pre[i]==0)
{
if(v+i>b) break;
if(dis[v+i]>dis[v]+1)
{
dis[v+i]=dis[v]+1;
que.push(v+i);
}
}
}
}
}
int main()
{
int t,a,b;
prime();
scanf("%d",&t);
while(t--)
{
scanf("%d %d",&a,&b);
bfs(a,b);
if(dis[b]!=INF)
printf("Case %d: %d\n",++k,dis[b]);
else printf("Case %d: %d\n",++k,-1);
}
return 0;
}
第二个是最短路:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
typedef int LL;
#define INF 0x3f3f3f3f
LL dis[1011];
LL vis[10111];
LL pri[1111];
LL dij(LL s,LL e) {
for(LL i=s;i<=e;++i) {
dis[i]=INF;
vis[i]=false;
}
dis[s]=0;
for(LL i=s;i<=e;++i) {
LL x,top=INF;
for(LL j=s;j<=e;++j) if(!vis[j] && dis[j]<top) top=dis[x=j];
if(top>=INF) break;
vis[x]=true;
for(LL j=2;j<x;++j) {
if(x%j==0&&!pri[j]) {
LL tt=x+j;
LL step=dis[x]+1;
if(tt>e) break;
if(!vis[tt]&&dis[tt]>step) dis[tt]=step;
}
}
}
return dis[e]>=INF?-1:dis[e];
}
int main() {
memset(pri,0,sizeof(pri));
for(LL i=2;i<=1000;++i) {
if(!pri[i]) {
for(LL j=i*2;j<1001;j+=i) pri[j]=1;
}
}
LL t;
LL Kase=0;
scanf("%d",&t);
while(t--) {
LL s,e;
scanf("%d%d",&s,&e);
printf("Case %d: ",++Kase);
if(s>e) puts("-1");
else printf("%d\n",dij(s,e));
}
return 0;
}