SPOJ:62 The Imp

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

SPOJ:62 The Imp_第1张图片

SPOJ:62 The Imp_第2张图片

题目的意思就是让你按这四种方式移动最后输出到原点的最小的曼哈顿距离的值。
虽然我也是看了题解,但是我是用另一种方法理解的。这四种移动方式可以组合成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的最小值,当然毫无头绪。。但是有时候角度一变可能问题会变得更好解决。
不过辗转处理,每次用最小的组合,可以使结果更“细”。


 

你可能感兴趣的:(SPOJ:62 The Imp)