icodelab 取走的弹珠(多组数据)

描述

有一个装弹珠的袋子,袋子一开始是空的,小明每次可以做两个操作:

1、向袋子里放入比上一次放入的个数多一个的弹珠。

2、从袋子里取出一个弹珠

当袋子为空时,小明只能执行第1个操作(显然第1次操作永远是放入一个弹珠)。 现在给出操作数n和操作后最终袋子里的弹珠数量k,求出请你求出小明总共拿走了多少个弹珠。

题目保证有解。

输入

输入第一行m,表示有m组数据(不超过10组);

接下来m行,每行有两个整数n和k,中间用空格隔开。

输出

输出m行,每行一个整数表示取走的弹珠总数

输入样例 1

2
9 11
1 1

输出样例 1

4
0

提示

n<=10^9

k<=10^18

思路

比如说有a次操作是放球,n-a次是取球
那么不论这n次操作顺序如何,结果都是一样的
也就是说 a*(a+1)/2-(n-a)=k
推导过程(✧◡✧):
a^2+a-2n+2a=2k
a^2+3a-2n-2k=0
放了a次球,不就是放了a(a+1)/2个球么
∴a^2+a-2n+2a=2k
   a^2+3a-2n-2k=0
   a=(-3+sqrt(9+8n+8k))/2

a是放球的次数
n-a就是取球的次数(也就是答案)
 
代码(超简短):
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

int m;
long long n,k,a;

int main () {
	scanf("%d",&m);
	while(m--) {
		scanf("%lld%lld",&n,&k);
		a=(sqrt(9+8*n+8*k)-3)/2;
		printf("%lld\n",n-a);
	}
	return 0;
}

 

猜你喜欢

转载自www.cnblogs.com/mysh/p/11300765.html