HDU 1030 Delta-wave

来源:互联网 发布:程序员标准着装 编辑:程序博客网 时间:2024/06/10 03:56

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1030


解析:

数学问题,可以看成三个方向的坐标系,然后在三个方向上每个方向去最小的步数。


在看这题之前,我们先看下一个简单的题目

 <1>

图示两个点,如果只能横向或者纵线走,从A到B的步数为(5-2)+(3-1)=5

在此坐标系中,每个方格有两个方向(横向、纵向,即x,y方向)

那么在此题中,不难看出每个三角形有三个方向(x,y,z)

X方向    


Y方向    


Z方向   


有了这些基础之后,我们需要求解的就是在某点在各个方向上面的位置

例如:点n

X:   rn = (int)ceil(sqrt(n));

Y:   leftn = (n - (rn-1)*(rn-1)+1)/2;

Z:   rightn = (rn*rn - n)/2+1;




代码

/*ID:muller8Name:  1030 Delta-waveReference: 数学问题,三方向的坐标系*/#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <algorithm>#include <vector>#include <cmath>using namespace std;#define MAXN 1005#define INF 1e9int  main(){    int m,n;    int rm,rn;    int leftm, leftn, rightm, rightn;    while(~scanf("%d%d", &m, &n)){        //表示第几行        rm = (int)ceil(sqrt(m));        rn = (int)ceil(sqrt(n));                //从左斜列数,第几列        leftm = (m - (rm-1)*(rm-1)+1)/2;        leftn = (n - (rn-1)*(rn-1)+1)/2;                //从右斜列数,第几列        rightm = (rm*rm - m)/2+1;        rightn = (rn*rn - n)/2+1;                printf("%d\n", (int)(abs(rm-rn)+abs(leftm-leftn)+abs(rightm-rightn)));    }    return 0;}

0 0