解题历程:
开始想的是用数学公式的方法,利用公式推出二次函数,再求出根,再用根求出答案,检查了一个小时,结果怎么改都有细微的偏差,最后发现答案先单调递减在单调递增,那么可以用二分答案的方法查找最小的答案,二分对细节的处理要求比较高,于是在二分中加入了一个限制,当二分的区间小于5时,就直接遍历五个答案判断
代码:
#include<bits/stdc++.h>
#define ll long long
#define endl "\n"
using namespace std;
ll zong(ll s,ll k,ll n)
{
return abs((k+k+s-1)*s-(k+s+k+n-1)*(n-s))/2;
}
int main(void )
{
//ios::sync_with_stdio(0);
//cin.tie(0),cout.tie(0);
int test=1;
cin>>test;
//string str="narek";
while(test--)
{
ll n,k;
cin>>n>>k;
ll l=0,r=n;
ll t=(l+r)/2;
while(1)
{
if(zong(t,k,n)<=zong(t+1,k,n)&&zong(t,k,n)<=zong(t-1,k,n))break;
if(r-l<100)
{
for(int i=l;i<=r;i++)
{
if(zong(i,k,n)<=zong(i+1,k,n)&&zong(i,k,n)<=zong(i-1,k,n))break;
}
}
if(zong(t,k,n)<zong(t+1,k,n)&&zong(t,k,n)>zong(t-1,k,n))
{
r=t;
t=(t+l)/2;
}
if(zong(t,k,n)>zong(t+1,k,n)&&zong(t,k,n)<zong(t-1,k,n))
{
l=t;
t=(t+r)/2;
}
}
cout<<zong(t,k,n)<<endl;
}
return 0;
}
反思:
以后要是推出的公式非常复杂,那么就不能用数学的方法进行求解,因为在计算的过程中会有精度丢失,最后输出会和答案发生细微的偏差
标签:二分,zong,971,ll,codeforces,cin,答案,test,div4 From: https://www.cnblogs.com/cavendishboys/p/18434177