CodeForces490D Chocolate

题目:

Description
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 is 5 × 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≤ 10的9次方) — the initial sizes of the first chocolate bar. The second line of the input contains integers a2, b2(1 ≤ a2, b2 ≤ 10的9次方) — 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 2的31次方- 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 Input
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

题目大意:
有两个矩形,它们的长和宽分别为a1, b1, a2, b2(均为整数),现在可以通过两种方式改变两个矩形的长或宽(可以改动任何一条边,但之后仍然是个矩形且边依旧都是整数)。
可以将某条边变为原来的1/2.
可以将某条边变为原来的2/3.
问至少要经多少步骤才能让两个矩形的面积相等(若有则输出所需时间以及最终结果,若没有则输出-1)。

一开始我没有想到好的方法,直到看了某些大神的博客后才略微有思路。

首先要解决的是是否存在一种方法让两个矩形最后的面积相等。由于这两种方法要么除以2, 要么除以3乘以2(但要保证之后的结果依旧是整数),因此我们可以先将它们的面积求出来,然后除去它们的因子2和3,看最后的面积能否相等,如果相等则有可能,反之没有。

如果有可能,则求出结果。我们可以在之前去除因子2和3的过程中统计一下两个面积中包含因子2和3的个数。因为要求出最小的执行步骤数,因此我们可以先判断两个面积中谁包含的因子3的个数最多(因为除以一个3会乘以一个2,导致包含2的个数不确定,从而无法得到最佳答案),谁包含的3多就处理谁,然后将长变为2/3,无法得到整数了就处理宽(但要注意除以3的个数)。然后依此对2进行处理即可。

参考代码:

#if __cplusplus < 201103L
    #error "please use C++11 implementations"
#endif
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <cmath>
using namespace std;
typedef long long ll;

ll mintime(ll &a1, ll &b1, ll &a2, ll &b2) {
    ll area1, area2;
    area1 = a1 * b1;
    area2 = a2 * b2;
    ll a = area1, b = area2;
    ll n2 = 0, n3 = 0, m2 = 0, m3 = 0;//第一个和第二个中分别包含素因子2和3的个数;
    while (a % 2 == 0 || a % 3 == 0) {
        if (a % 2 == 0) {
            a = a / 2;
            ++n2;
        }
        else {
            a = a / 3;
            ++n3;
        }
    }
    while (b % 2 == 0 || b % 3 == 0) {
        if (b % 2 == 0) {
            b = b / 2;
            ++m2;
        }
        else {
            b = b / 3;
            ++m3;
        }
    }
    if (a != b) return -1;
    else {
        ll ans = abs(n3 - m3);//两个面积之间相差的素因子3的个数;
        if (m3 > n3) {//乘以三分之二: 扣掉3在补回2;
            m3 -= ans;
            m2 += ans;
            ll ans1 = ans;
            while (a2 % 3 == 0 && ans1) {
                a2 = a2 / 3 * 2;//乘以三分之二;
                --ans1;
            }
            while (b2 % 3 == 0 && ans1) {
                b2 = b2 / 3 * 2;
                --ans1;
            }
        }
        else {
            n3 -= ans;
            n2 += ans;
            ll ans1 = ans;
            while (a1 % 3 == 0 && ans1) {
                a1 = a1 / 3 * 2;
                --ans1;
            }
            while (b1 % 3 == 0 && ans1) {
                b1 = b1 / 3 * 2;
                --ans1;
            }
        }
        ans += abs(m2 - n2);//相差因子2的个数;     
        if (m2 > n2) {
            ll ans1 = abs(m2 - n2);
            while (a2 % 2 == 0 && ans1) {
                a2 = a2 / 2;
                --ans1;
            }
            while (b2 % 2 == 0 && ans1) {
                b2 = b2 / 2;
                --ans1;
            } 
        }
        else {
            ll ans1 = abs(m2 - n2);
            while (a1 % 2 == 0 && ans1) {
                a1 = a1 / 2;
                --ans1;
            }
            while (b1 % 2 == 0 && ans1) {
                b1 = b1 / 2;
                --ans1;
            }
        }
        return ans;
    }   
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    ll a1, b1, a2, b2;
    cin >> a1 >> b1 >> a2 >> b2;
    ll ans = mintime(a1, b1, a2, b2);
    cout << ans << endl;
    if (ans != -1)
        cout << a1 << " " << b1 << endl << a2 << " " << b2 << endl;
    return 0;
}

理解还不是很透彻(毕竟不是自己想出来的),欢迎大家提出意见。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容

  • **2014真题Directions:Read the following text. Choose the be...
    又是夜半惊坐起阅读 9,363评论 0 23
  • 文/白卉 宝贝: 提起你幸福感就爆棚,一直以来你都是我们的骄傲,这并不是你学习有多好。而是你的聪明乖巧体贴善良真诚...
    白卉阅读 600评论 5 6
  • 这些年,我都不敢回头望,也慢慢忘记了回忆的滋味,对于大学时代,对于高中时代,我只能偶尔叹息时间匆匆溜走,物是人非,...
    芷钰阅读 323评论 0 0
  • 文∥寒蝉之悦 相信许多人都看过《最强大脑》中逆算天才周玮的精彩表现,大家称他为“中国雨人”,可惜他是个中度智障。 ...
    小鹿呱呱阅读 1,400评论 1 1
  • 《雨季》 朦朦的烟台 在下雨的季节里 我遥望北方 那年,也是五月 大连港边榆树正发芽 那边风沙正浓 围巾里还装着对...
    点点星灯阅读 104评论 0 1