Delta-wave
- 题目链接
- Delta-wave
- 题目大意
给你一个奇怪的三角形,上面依照顺序有1~n个数,每个数在一个小的三角形中,我们可以跨越三角形的边,跨越一条边算走1步,现在问你从1走到n,最短的距离是多少。
- 题解
一个数学问题,不过我是贪出来的,在这里主要是如下三点:
1.有些上下两条边相邻的三角形,从上面可以直接跨越至下一层而且路径一定是最短的。
2.如果我们一直垂直往下走,我们是可以直接求出在目标层的位置的,这样,我们在现在就算出现在相对目标层的位置,如果在左边,我们就向右走,如果在右边,我们就向左走。
3.如上两条策略,优先选择第一条(可以证明如果可以的话,第一条策略一定是最优的)那么我们就先用数学求出所在的层数和位置,再判断现在是否要向下走,如果要向下走,我们依次判断如上3条策略就可以了。如果已经同层,则直接判断位置的差。
- 代码
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <cstdlib>
using namespace std;
int n,m,x1,y11,x2,y2,x,ans;
int main()
{
while (scanf("%d%d",&n,&m)!=EOF)
{
ans=0;
if (n>m)
{
int k;
k=n; n=m; m=k;
}
x=n;
x1=(int) sqrt(n-0.5)+1;
y11=n-(x1-1)*(x1-1);
x2=(int) sqrt(m-0.5)+1;
y2=m-(x2-1)*(x2-1);
while (x1<x2)
{
if (x1%2==x%2)
{
x1++; y11++; x=(x1-1)*(x1-1)+y11;
ans++;
continue ;
}
int p=x2-x1+y11;
if (p>y2)
{
y11--; x--; ans++;
}
else if (p<y2)
{
y11++; x++; ans++;
}
else
{
x1++; y11++; x=(x1-1)*(x1-1)+y11;
ans+=3;
}
}
ans+=abs(y2-y11);
printf("%d\n",ans);
}
return 0;
}