codeforces 490D Chocolate(数学或搜索)

时间:2021-05-24 05:15:19

题目链接

D. Chocolatetime limit per test1 secondmemory limit per test256 megabytesinputstandard inputoutputstandard output

Polycarpus likes giving presents to Paraskevi. He has bought two chocolate bars, each of them has the shape of a segmented rectangle. The first bar is a1 × b1 segments large and the second one is a2 × b2 segments large.

Polycarpus wants to give Paraskevi one of the bars at the lunch break and eat the other one himself. Besides, he wants to show that Polycarpus's mind and Paraskevi's beauty are equally matched, so the two bars must have the same number of squares.

To make the bars have the same number of squares, Polycarpus eats a little piece of chocolate each minute. Each minute he does the following:

  • he either breaks one bar exactly in half (vertically or horizontally) and eats exactly a half of the bar,
  • or he chips of exactly one third of a bar (vertically or horizontally) and eats exactly a third of the bar.

In the first case he is left with a half, of the bar and in the second case he is left with two thirds of the bar.

Both variants aren't always possible, and sometimes Polycarpus cannot chip off a half nor a third. For example, if the bar is 16 × 23, then Polycarpus can chip off a half, but not a third. If the bar is 20 × 18, then Polycarpus can chip off both a half and a third. If the bar is5 × 7, then Polycarpus cannot chip off a half nor a third.

What is the minimum number of minutes Polycarpus needs to make two bars consist of the same number of squares? Find not only the required minimum number of minutes, but also the possible sizes of the bars after the process.

Input

The first line of the input contains integers a1, b1 (1 ≤ a1, b1 ≤ 109) — the initial sizes of the first chocolate bar. The second line of the input contains integers a2, b2 (1 ≤ a2, b2 ≤ 109) — the initial sizes of the second bar.

You can use the data of type int64 (in Pascal), long long (in С++), long (in Java) to process large integers (exceeding 231 - 1).

Output

In the first line print m — the sought minimum number of minutes. In the second and third line print the possible sizes of the bars after they are leveled in m minutes. Print the sizes using the format identical to the input format. Print the sizes (the numbers in the printed pairs) in any order. The second line must correspond to the first bar and the third line must correspond to the second bar. If there are multiple solutions, print any of them.

If there is no solution, print a single line with integer -1.

Sample test(s)input
2 6
2 3
output
1
1 6
2 3
input
36 5
10 16
output
3
16 5
5 16
input
3 5
2 1
output
-1

题意:对于一个n*m格子的巧克力,可以进行以下两种操作:

1,按行或按列切掉巧克力的一半,吃掉这一半。

2,按行或按列切掉巧克力的三分之一,吃掉这三分之一。

进行完以上两种操作,剩下的巧克力的每个单位格子(1*1的格子)必须是完整的。

现在有两块巧克力,问让两块巧克力面积相等最少要操作多少次,并输出两块巧克力的形状。

题解:

第一种方法:由于每次让巧克力的面积减少一半或三分之一,所以1块巧克力不会操作很多次,我们可以bfs一块巧克力能达到的所有状态。

代码如下:

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<string>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<stdlib.h>
#include<vector>
#define inff 0x3fffffff
#define nn 110000
#define mod 1000000007
typedef long long LL;
const LL inf64=inff*(LL)inff;
using namespace std;
int a1,b1;
int a2,b2;
map<pair<int,int>,int>ma1,ma2;
map<LL,pair<int,int> >m1,m2;
queue<pair<int,int> >que;
void bfs()
{
pair<int,int>tem;
if(a1>b1)
swap(a1,b1);
tem=make_pair(a1,b1);
ma1[tem]=0;
que.push(tem);
pair<int,int>sta;
int ix,fc;
LL mj;
while(que.size())
{
sta=que.front();
mj=sta.first;
mj=mj*sta.second;
if(m1.count(mj)==0)
m1[mj]=sta;
que.pop();
if(sta.first%2==0)
{
tem=make_pair(sta.first/2,sta.second);
if(ma1.count(tem)==0)
{
ma1[tem]=ma1[sta]+1;
que.push(tem);
}
}
if(sta.first%3==0)
{
tem=make_pair(sta.first/3*2,sta.second);
if(ma1.count(tem)==0)
{
ma1[tem]=ma1[sta]+1;
que.push(tem);
}
}
if(sta.second%2==0)
{
ix=sta.second/2,fc=sta.first;
if(ix>fc)
swap(ix,fc);
tem=make_pair(ix,fc);
if(ma1.count(tem)==0)
{
que.push(tem);
ma1[tem]=ma1[sta]+1;
}
}
if(sta.second%3==0)
{
ix=sta.second/3*2,fc=sta.first;
if(ix>fc)
swap(ix,fc);
tem=make_pair(ix,fc);
if(ma1.count(tem)==0)
{
que.push(tem);
ma1[tem]=ma1[sta]+1;
}
}
}
}
void solve()
{
pair<int,int>tem;
if(a2>b2)
swap(a2,b2);
tem=make_pair(a2,b2);
ma2[tem]=0;
que.push(tem);
pair<int,int>sta;
int ix,fc;
int ans=inff;
LL mj;
LL mt;
while(que.size())
{
sta=que.front();
mj=sta.first;
mj=mj*sta.second;
if(m2.count(mj)==0)
{
m2[mj]=sta;
if(m1.count(mj))
{
tem=m1[mj];
if(ma1[tem]+ma2[sta]<ans)
{
ans=ma1[tem]+ma2[sta];
mt=mj;
}
}
}
que.pop();
if(sta.first%2==0)
{
tem=make_pair(sta.first/2,sta.second);
if(ma2.count(tem)==0)
{
ma2[tem]=ma2[sta]+1;
que.push(tem);
}
}
if(sta.first%3==0)
{
tem=make_pair(sta.first/3*2,sta.second);
if(ma2.count(tem)==0)
{
ma2[tem]=ma2[sta]+1;
que.push(tem);
}
}
if(sta.second%2==0)
{
ix=sta.second/2,fc=sta.first;
if(ix>fc)
swap(ix,fc);
tem=make_pair(ix,fc);
if(ma2.count(tem)==0)
{
que.push(tem);
ma2[tem]=ma2[sta]+1;
}
}
if(sta.second%3==0)
{
ix=sta.second/3*2,fc=sta.first;
if(ix>fc)
swap(ix,fc);
tem=make_pair(ix,fc);
if(ma2.count(tem)==0)
{
que.push(tem);
ma2[tem]=ma2[sta]+1;
}
}
}
if(ans==inff)
{
puts("-1");
}
else
{
printf("%d\n",ans);
printf("%d %d\n",m1[mt].first,m1[mt].second);
printf("%d %d\n",m2[mt].first,m2[mt].second);
}
}
int main()
{
while(scanf("%d%d%d%d",&a1,&b1,&a2,&b2)!=EOF)
{
ma1.clear();
ma2.clear();
m1.clear();
m2.clear();
bfs();
solve();
}
return 0;
}
第二种方法:

第一种操作相当于将一个巧克力的面积乘以1/2,第二种操作相当于将一个巧克力的面积乘以2/3。将两块巧克力的面积除去素因子2和3以后,若剩下的数相等,则面积可以相等。然后我们贪心的让两个巧克力的面积包含的2和3因子数相同,并且让2 和3的因子个数最多即可。

代码如下:

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<string>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<stdlib.h>
#include<vector>
#define inff 0x3fffffff
#define nn 6100
#define mod 1000000007
typedef long long LL;
const LL inf64=inff*(LL)inff;
using namespace std;
LL a1,b1,a2,b2;
int main()
{
while(scanf("%I64d%I64d%I64d%I64d",&a1,&b1,&a2,&b2)!=EOF)
{
LL ix=a1*b1;
int n2,n3,m2,m3;
n2=n3=m2=m3=0;
while(ix%2==0)
{
ix/=2;
n2++;
}
while(ix%3==0)
{
ix/=3;
n3++;
}
LL fc=a2*b2;
while(fc%2==0)
{
fc/=2;
m2++;
}
while(fc%3==0)
{
fc/=3;
m3++;
}
if(ix!=fc)
{
puts("-1");
}
else
{
int ans=abs(m3-n3);
if(m3>n3)
{
m3-=ans;
m2+=ans;
int my=ans;
while(a2%3==0&&my)
{
a2=a2/3*2;
my--;
}
while(b2%3==0&&my)
{
b2=b2/3*2;
my--;
}
}
else
{
n3-=ans;
n2+=ans;
int my=ans;
while(a1%3==0&&my)
{
a1=a1/3*2;
my--;
}
while(b1%3==0&&my)
{
b1=b1/3*2;
my--;
}
}
ans+=abs(n2-m2);
if(n2>m2)
{
int my=abs(n2-m2);
while(a1%2==0&&my)
{
a1/=2;
my--;
}
while(b1%2==0&&my)
{
b1/=2;
my--;
}
}
else
{
int my=abs(n2-m2);
while(a2%2==0&&my)
{
a2/=2;
my--;
}
while(b2%2==0&&my)
{
b2/=2;
my--;
}
}
printf("%d\n",ans);
printf("%I64d %I64d\n",a1,b1);
printf("%I64d %I64d\n",a2,b2);
}
}
return 0;
}