http://codeforces.com/contest/371/problem/B
暴力一点的写法:bfs搜索(可以过,但是有更优的做法),共六种拓展方向,优化一点是:吃大的。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#define LL long long
using namespace std;
int a0,b0,ans=100000000;
struct H{
int a;
int b;
int step=0;
};
queue <H> q;
int flag=0,f=0;
void change1(H l)
{
H p;
if(l.a%2==0){
p=l;
p.a/=2;p.step++;
if(p.a==p.b){flag=1;ans=min(ans,p.step);}
q.push(p);
}
if(l.a%3==0){
p=l;
p.a=p.a/3;p.step++;
if(p.a==p.b){flag=1;ans=min(ans,p.step);}
q.push(p);
}
if(l.a%5==0){
p=l;
p.a=p.a/5;p.step++;
if(p.a==p.b){flag=1;ans=min(ans,p.step);}
q.push(p);
}
}
void change2(H l)
{
H p;
if(l.b%2==0){
p=l;
p.b=p.b/2;p.step++;
if(p.a==p.b){flag=1;ans=min(ans,p.step);}
q.push(p);
}
if(l.b%3==0){
p=l;
p.b=p.b/3;p.step++;
if(p.a==p.b){flag=1;ans=min(ans,p.step);}
q.push(p);
}
if(l.b%5==0){
p=l;
p.b=p.b/5;p.step++;
if(p.a==p.b){flag=1;ans=min(ans,p.step);}
q.push(p);
}
}
int main()
{
scanf("%d%d",&a0,&b0);
if(a0==b0){printf("0
");return 0;}
H l;
l.a=a0;l.b=b0;
q.push(l);
while(!q.empty())
{
f=0;
l=q.front();
q.pop();
if(l.a==l.b) break;
if(l.a>l.b) change1(l);
else change2(l);
if(flag) break;
}
if(flag)printf("%d
",ans);
else printf("-1
");
return 0;
}
第二种做法:根据题意可知,两块蛋糕最后一定变为a,b的最大公约数c,结果就是a/c,b/c对于2,3,5分解质因数能分解几次的次数之和,若不能分解为1,就是-1
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#define LL long long
using namespace std;
int a,b,c;
int gcd(int x,int y)
{
if(x<y) swap(x,y);
if(x%y==0) return y;
return gcd(y,x%y);
}
int tear(int x)
{
int y=0;
while(x%2==0)
y++,x/=2;
while(x%3==0)
y++,x/=3;
while(x%5==0)
y++,x/=5;
if(x!=1)return -1;
return y;
}
int main()
{
scanf("%d%d",&a,&b);
if(a==b){printf("0
");return 0;}
c=gcd(a,b);
int a1=tear(a/c);int a2=tear(b/c);
if(a1>=0&&a2>=0) printf("%d
",a1+a2);//注意判断条件:应该是都不是-1
else printf("-1
");
return 0;
}