SPOJ:62 The Imp

看了题解才做出来的题,虽然做法是一样的,但解释略有不同。
先贴上题解。

题目的意思就是让你按这四种方式移动最后输出到原点的最小的曼哈顿距离的值。
虽然我也是看了题解,但是我是用另一种方法理解的。这四种移动方式可以组合成N种移动方式。也就是说每个IMP可能到达的位置都可以看做是一步到达。所以IMP的每个曼哈顿距离可以直接等于每种移动方式的|x|+|y|。所以我们只需要组合出一种|x|+|y|最小的移动方式来即可。

 

怎么最小的移动方式求呢?用辗转组合即可。
两种移动方式组合不断直至得到更小的移动方式,用这更小的与原来较小的移动方式再不断组合,直至得到最小的便是最终结果。


注意一些细节最终位置不能是原点,所以曼哈顿距离不能是0;两种移动方式组合不只是相减,也可以相加。

 

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
struct Move
{
    int x,y;
    Move operator -(Move p)
    {
       Move t;
       t.x=x-p.x;t.y=y-p.y;
       return t;
    }
    Move operator +(Move p)
    {
       Move t;
       t.x=x+p.x;t.y=y+p.y;
       return t;
    }

};
int MHdis(Move a)
{
    return abs(a.x)+abs(a.y);
}
Move compute(Move a,Move b)
{
    while(MHdis(a-b)<MHdis(a)&&MHdis(a-b)) a=a-b;
    while(MHdis(a+b)<MHdis(a)&&MHdis(a+b)) a=a+b;
    return a;
}
int main()
{
   int T=10;
   while(T--)
   {
       Move A,B;
       scanf("%d%d%d%d",&A.x,&A.y,&B.x,&B.y);
       Move mx,mn,t;
       if(MHdis(A)>MHdis(B)){mx=A;mn=B;}
       else {mx=B;mn=A;}
        while(MHdis(t=compute(mx,mn))<MHdis(mn))
        {
               mx=mn;
               mn=t;
        }
       printf("%d\n",MHdis(mn));
   }
   return 0;
}


 

有时候思考问题的角度也比较重要,一开始我尝试用数学的角度求|am+cn|+|bm+dn|=val的最小值,当然毫无头绪。。但是有时候角度一变可能问题会变得更好解决。
不过辗转处理,每次用最小的组合,可以使结果更“细”。


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值