克拉克是一名人格分裂患者.某一天克拉克变成了一名数论研究者,在研究数字.
他想到了一个题:给定非负整数 x 和正整数 k ,可以做若干操作,每次操作是以下两种方法之一:
1. x=x−k
2. x=⌊x√⌋2
现在克拉克想知道,这个整数最少经过多少次操作可以变成 0 .
Input
第一行是一个正整数T(1≤T≤100),表示数据组数. 每组数据只有一行两个整数x, k(0≤x≤10^18, 1≤k≤2).
Output
每组数据输出一行一个整数,表示最少的操作数.若不存在方案,输出-1
Input示例
2 2 1 3 2
Output示例
2 -1
#include <cstdio>
using namespace std;
typedef long long ll;
const ll INF = 1e10;
ll x, k;
ll sqrt(ll x)
{
ll left = -1;
ll right = INF;
ll mid;
while (left < right - 1)
{
mid = left + (right - left) / 2;
if (mid * mid > x)
{
right = mid;
}
else if (mid * mid < x)
{
left = mid;
}
else
{
return mid;
}
}
return left;
}
int main()
{
int T;
scanf("%d", &T);
while (T--)
{
scanf("%lld%lld", &x, &k);
if (x == 0)
{
printf("0\n");
continue;
}
ll y = sqrt(x);
if (k == 1)
{
if (x == 1)
{
printf("1\n");
continue;
}
if (y * y == x)
{
printf("%lld\n", y * 2 - 1);
}
else
{
printf("%lld\n", y * 2);
}
}
else
{
if (x == 1 || x == 3)
{
printf("-1\n");
}
else if (x == 2)
{
printf("1\n");
}
else if (x == 5)
{
printf("3\n");
}
else
{
ll t = sqrt(x - 1);
if (y * y == x || t * t == x - 1)
{
printf("%lld\n", y * 2 - 2);
}
else
{
printf("%lld\n", y * 2 - 1);
}
}
}
}
return 0;
}