现在有两个块巧克力一块大小是a1 × b1 的,另外一块大小是a2 × b2 的。
现在要把两块巧克力变成面积一样大小,可以使用下列两种方法:
· 可以沿横向或纵向的网格线分成两等分,然后吃掉其中的一份。
· 可以沿横向或纵向的网格线分成2/3,1/3的两份,吃掉小的那一份。
因此使用第一种方法会留一半巧克力,用第二种方法会留下2/3巧克力。
两种方法并不总是可行的,有些时候两种方法都不能再用了。比如巧克力大小是16 × 23的时候,可以使用第一种方法,但是不能使用第二种方法。当大小是20 × 18的时候,可以使用第一种方法或者第二种方法。如果大小是5 × 7的时候,两种方法都不能使用。
问最少要操作几次才能使得两块巧克力的面积是一样的。
单组测试数据。 第一行有两个整数a1, b1 (1 ≤ a1, b1 ≤ 10^9),表示第一块巧克力的大小。 第二行有两个整数a2, b2 (1 ≤ a2, b2 ≤ 10^9),表示第二块巧克力的大小。
对于每一组数据输出占一行,输出一个整数表示最小步数,如果无法达到输出-1。
2 6 2 3
1
题解:思路真的是很重要orz。。。
讨论区大佬。。
注意这里题目要求只需操作后的面积相等,而非完全相等。于是我们只关心两块巧克力的面积(s1和s2),不关心具体长宽关系。
由于除数只有2和3,那么当s1和s2将2和3完全除尽后,s1与s2是否相等决定了此题是否有解。
对于有解的情况,在除尽2和3的过程中,我们可以把除以2看作是进行了一次操作1,把除以3看作是进行了一次操作2和一次操作1。
设我们对面积s一共除以了n次2和m次3,那么就是进行了n+m次操作1,m次操作2。
由于我们想将s1与s2以尽量少的操作数使得其相等,那么答案,即为两种操作的差的绝对值之和。(差的绝对值表示你大的边要操作几次才能变成另外一个小的边)
代码:
#include<cstring>
#include<algorithm>
#include<queue>
#include<iostream>
#include<cmath>
#include<cstdio>
#include<ctime>
using namespace std;
long long aa,bb,cc,dd,a,b,c,d;
int main()
{
std::ios::sync_with_stdio(false);
cin>>a>>b>>c>>d;
for (;a%2==0;aa++)a/=2;
for (;b%2==0;aa++)b/=2;
for (;a%3==0;bb++,aa++)a=a/3;
for (;b%3==0;bb++,aa++)b=b/3;
for (;c%2==0;cc++)c/=2;
for (;d%2==0;cc++)d/=2;
for (;c%3==0;dd++,cc++)c=c/3;
for (;d%3==0;dd++,cc++)d=d/3;
if (a*b!=c*d)cout<<-1;
else cout<<abs(aa-cc)+abs(bb-dd);
}