toj1339

来源:互联网 发布:javascript delay函数 编辑:程序博客网 时间:2024/06/05 10:54
/*要求两步差最多为1, 那么很容易想到序列应该是先增后减的。 关注以下序列:11 11 2 11 2 2 11 2 3 2 11 2 3 3 2 1...和分别为1,2,4,6,9,12...很容易想象,如果两数之差为10(上述9,12间),只需要判断9和12对应的两个序列即可:1 2 3 2 1......91 2 3 3 2 1....12第一个9对应的是没有办法在不增加步数的情况下使总和增加的(首尾为1,且满足先增后减) 第二个可以逐步减少产生和为11,10的序列:1 2 3 2 2 1......111 2 2 2 2 1......10类似的,如果两数差在6,9之间,那么总和为6的序列1,2,2,1接近于一种类似“饱和”的状态,无法通过增加某一步或者修改某几步的长度达到总和为7乃至更高的“效果”,而通过逐步减少,却可以把总和为9的序列变成总和为8,7的序列(不改变步数的前提下)。 如此便可得出规律, 只要卡这些特殊序列的总和,就可以得解。考虑第n个序列:如果n为奇数,那么各项为:1, 2, 3,...(n-1)/2 - 1, (n-1)/2, (n-1)/2 - 1, (n-1)/2 - 2,... 3, 2, 1总和为(n+1)*(n+1)/4;如果n为偶数,那么各项为: 1, 2, 3,...(n-1)/2 - 1,(n-1)/2, (n-1)/2, (n-1)/2 - 1, ..., 3, 2, 1总和为n*(n+2)/4.对于一个差rec,只需要判断它所处的“区间”,也就是在上述序列的哪两项之间即可,判断出后向上取整。如对于rec=18, 分别计算两个方程(n+1)*(n+1)=4*rec解出正数解left = ceil(2*sqrt(rec)-1),由n*(n+2)=4*rec+1解出正数解right = ceil(sqrt(4*rec+1)-1).因为下面两个方程分别是在n为奇数和偶数的条件下得出,那么我们看Left是否为奇数就知道它是不是解,同理right如果为偶数,那么答案就是right了。并且两者一定有且仅有一个可以满足。 */ #include <cstdio>#include <cmath>const double eps = 1e-8;typedef long long ll;int main() {int T;ll x, y, ans, rec;scanf(" %d", &T);while (T--) {scanf(" %lld %lld", &x, &y);rec = y - x;ll odd = 2*sqrt(rec) - 1 + eps;ll even = sqrt(4*rec+1.0) - 1 + eps;if ((odd+1)*(odd+1) == 4*rec) {ans = odd;} else if ((even+1)*(even+1) == 4*rec+1) {ans = even;} else {odd += (odd&1) ? 2 : 1;even += (even&1) ? 1 : 2;ans = odd < even ? odd : even;}printf("%lld\n", ans);}return 0;}

0 0