codeforces round 971(div4)E(二分答案,禁用数学方法)

解题历程:

开始想的是用数学公式的方法,利用公式推出二次函数,再求出根,再用根求出答案,检查了一个小时,结果怎么改都有细微的偏差,最后发现答案先单调递减在单调递增,那么可以用二分答案的方法查找最小的答案,二分对细节的处理要求比较高,于是在二分中加入了一个限制,当二分的区间小于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;
}

反思:

以后要是推出的公式非常复杂,那么就不能用数学的方法进行求解,因为在计算的过程中会有精度丢失,最后输出会和答案发生细微的偏差

posted @ 2024-09-26 19:54  C微  阅读(17)  评论(0)    收藏  举报