计蒜客 folding

 folding

As you can remember, Alex is fond of origami. She switched from squares to rectangles, and rectangles are much more difficult to master. Her main interest is to determine what is the minimum possible number of folds required to transform W × H rectangle to w × h one. The result of each fold should also be rectangular, so it is only allowed to make folds that are parallel to the sides of the rectangle.

Help Alex and write a program that determines the minimum required number of folds.

Input

The first line of the input contains two integers W and H — the initial rectangle dimensions. The second line contains two more integers w and h — the target rectangle dimensions (1 W, H, w, h 10910^9109).

Output

Output a single integer — the minimum required number of folds to transform the initial rectangle to the target one.

If the required transformation is not possible, output 1. 

样例输入1
2 7
2 2
样例输出1
2
样例输入2
10 6
4 8
样例输出2
2
样例输入3
5 5
1 6
样例输出3
-1


In the first example you should fold 2×7 rectangle to 2×4, and then to 2×2.
In the second example you should fold 10
×6 rectangle to 10×4, then to 8×4, and rotate it to 4×8.

In the third example it is impossible to fold 5 × 5 rectangle to 1 × 6 one (remember that folds must be parallel to the rectangle sides).



题意:
给定两个矩形的纸的长宽,问能否通过平行于边的折叠操作使第二个变成第一个的长宽,输出最小次数,否则输出 -1

思路:
长度为3的纸最多折叠成的长度为2,即最多减少了1。(3/2=1)
长度为4的纸最多叠成的长度为2,即最多减少了2。(4/2=2)
(奇数偶数最多减少的都是本身除以2)

所以可以循环每次减最大值(大于等于目标规格,使第一个变第二个),最后若减不了又不到则次数加一。
然后变化顺序再来一遍取最小值,因为不知道最佳搭配。

代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
using namespace std;
#define INF 0x3f3f3f3f

int main()
{
    int n,m;
    int a,b;
    scanf("%d%d",&n,&m);
    scanf("%d%d",&a,&b);
    if(n>m)swap(n,m);
    if(a>b)swap(a,b);
    int g=0,h=0;
    if(a>n || b>m)printf("-1\n");
    else
    {
        int ans=INF;
        for(int i=0;i<2;i++)
        {
            if(i==1)
                swap(n,m);
            
            g=0,h=0;
            int maxn=n/2;
            int nn=n;
            while(nn-maxn>=a && n!=a && maxn!=0)
            {
                g++;
                nn-=maxn;
                maxn=nn/2;
            }
            if(nn>a)g++;
            
            maxn=m/2;
            int mm=m;
            while(mm-maxn>=b && m!=b && maxn!=0)
            {
                h++;
                mm-=maxn;
                maxn=mm/2;
            }
            if(mm>b)h++;
            
            ans=min(ans,g+h);
        }
        
        printf("%d\n",ans);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值