跟前面的一题有些类似.
题意是给出两个距离, 求从一个到另一个需要走的步数.
每一步走的距离必须从1开始, 以1结束, 可以大于, 等于, 或小于上一步.
我的算法是求出小于距离之差n的最大距离dis, 相减得到一个数k, 这个数就是还需要走的距离. 对(k / 最大一步距离)向上取整, 结果就是另外要多走的步数.
先来看看dis = 1 + 2 + ..i + (i + 1) + i... + 2 + 1这个式子. i + 1是最大一步距离.如果忽略其他条件的话, 这个是"对称"的, 他的值就是i(i + 1) + (i + 1)
联系题目, 我们所要做的无非就是在这个式子中插入距离num (num <= max), 使之结果等于差值n.
n - dis, 得到的值就是要插入的距离k. 所以只要距离k / max, 结果向上取整就行, 得到还要额外走的步数.
上面的描述太混乱了...再用最简单的语句说一遍我的思路:
求出最接近距离之差的1 + 2 +....+ i + (i + 1)+ i + ... + 2 + 1, 再把他们的差除以i, 向上取整得到值a
最后的答案就是a + i * 2 + 1
详情见代码
#include <cstdio>
#include <cmath>
using namespace std;
int main()
{
//freopen("input.txt", "r", stdin);
int T;
double n, sum, tempsum;
double a, b;
int i, cnt;
scanf("%d", &T);
while (T--)
{
bool flag = false, sflag = false;
i = 1;
scanf("%lf%lf", &a, &b);
n = abs(a - b);
if ((int)n == 3) //首先排除几种特殊情况
{
printf("3\n");
continue;
}
else if ((int)n == 0)
{
printf("0\n");
continue;
}
else if ((int)n == 1)
{
printf("1\n");
continue;
}
else if ((int)n == 2)
{
printf("2\n");
continue;
}
while (true)
{
tempsum = i * (i + 1) + (i + 1); //储存暂时的数据, 因为我们要的是不超过n的最大sum
if (tempsum <= n)
{
sum = tempsum;
flag = true;
i++;
}
else
{
if (flag)
i--;
break;
}
}
cnt = i * 2 + 1 + ceil((n - sum) / (i + 1));
printf("%d\n", cnt);
}
return 0;
}