toj1339

/*
	要求两步差最多为1, 那么很容易想到序列应该是先增后减的。 
	关注以下序列:
	1
	1 1
	1 2 1
	1 2 2 1
	1 2 3 2 1
	1 2 3 3 2 1
	...
	和分别为1,2,4,6,9,12...
	很容易想象,如果两数之差为10(上述9,12间),只需要判断9和12对应的两个序列即可:
	1 2 3 2 1......9
	1 2 3 3 2 1....12
	第一个9对应的是没有办法在不增加步数的情况下使总和增加的(首尾为1,且满足先增后减) 
	第二个可以逐步减少产生和为11,10的序列:
	1 2 3 2 2 1......11
	1 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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值