题意:
就是计算从a转换到b的最少步数,a可以转化到a+x,x是a的因子。
注意:
1、只有a>b的时候,是-1;
2、当a=b的时候,是0;
思路:dp+bfs
先预处理100000个数的因子数存在countt数组内,并将每个数的因子存到num数组内。
然后bfs。
代码:
#pragma comment(linker, "/STACK:36777216")
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<vector>
using namespace std;
#define LL __int64
#define maxn 100001
int countt[maxn];
struct node {
int step;
int number;
friend bool operator < (node a,node b) {
return a.step>b.step;
};
};
int num[maxn][130];
void init() {
countt[0]=0;
memset(num,0,sizeof(num));
for(int i=1; i<=100000; i++) {
int cnt=0;
for(int j=1; j<=(int)sqrt(i*1.0); j++) {
if(i%j==0) {
num[i][cnt++]=j;
if(j*j!=i) {
num[i][cnt++]=i/j;
}
}
}
countt[i]=cnt;
}
}
int b;
bool bfs(int pos) {
priority_queue<node>que;
bool vis[maxn];
memset(vis,false,sizeof(vis));
node p1;
p1.number=pos;
p1.step=0;
vis[pos]=true;
que.push(p1);
while(!que.empty()) {
node p2;
p2=que.top();
que.pop();
// printf("*****%d\n",countt[p2.number]);
for(int i=0; i<countt[p2.number]; i++) {
p1.number=p2.number+num[p2.number][i];
p1.step=p2.step+1;
if(p1.number>b) {
continue;
}
if(vis[p1.number]) {
continue;
}
vis[p1.number]=true;
if(p1.number==b) {
printf("%d\n",p1.step);
return true;
}
que.push(p1);
}
}
return false;
}
int main() {
init();
int a;
while(~scanf("%d%d",&a,&b)) {
if(a==b) {
printf("0\n");
continue;
}
if(a>b) {
printf("-1\n");
} else {
if(!bfs(a)) {
// printf("***");
printf("-1\n");
}
}
}
return 0;
}