NOI题库_微积分_NOI2001反正切函数的应用

对于那个式子,我们可以展开得到(a*b+a*c)=b*c-1 => b=(a*c+1)/(c-a)   => b+c=(c*c+1)/(c-a)很显然  a不等于c那么我们可以构造一个函数 f(c)=b+c=(c*c+1)/(c-a), 要求极值 ,那么我们可以先求导, f(x)的导数g(x)=c*c-2*a*c-1因为极值出的导数为零,那么就相当于是一个一元二次方程.此时c=
摘要由CSDN通过智能技术生成

对于那个式子,我们可以展开得到(a*b+a*c)=b*c-1 => b=(a*c+1)/(c-a)   => b+c=(c*c+1)/(c-a)

很显然  a不等于c

那么我们可以构造一个函数 f(c)=b+c=(c*c+1)/(c-a), 要求极值 ,

那么我们可以先求导, f(x)的导数g(x)=c*c-2*a*c-1

因为极值出的导数为零,那么就相当于是一个一元二次方程.

此时c=a + sqrt(a*a+1)或a - sqrt(a*a+1) 分析导数图像可以得出f(c)最小时c=a + sqrt(a*a+1).

但是我们取到的是可能无理数啊那怎么办?

在第一象限内可以看做是 f(c) 单峰函数(导数另一个零点在第二象限)那么我们可以同时递增和递减 c 然后验证b是否为整数 找到的第一个可行解即为最优解


听CA爷说貌似还可以来枚举因数?反正我不会...   %%%%CA爷

附代码:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;




int a,b,c;
int Check(double c)
{
    if(a==c )
       return -1;
double b=(a*c+1)/(c-a);
if(c<=0||b<=0)
  return -1;
    int b_i=(int)b,c_i=(int)c;
return a*(c_i+b_i)!=(c_i*b_i-1)?-1:b_i+c_i;
}


int main()
{

double Mid;
scanf("%d",&a);
Mid=(2.0*a+sqrt(4.0*a*a+4.0))/2.0; 
int ans=Check((int)Mid);
    int tp=-1,y;
    int b=((int)Mid-1),c=b+2;

do{
y=Check(b);
if(y!=-1)
 tp=y;
y=Check(c);
if(y!=-1)
 if(tp!=-1)
  tp=min(tp,y);
 else tp=y;
else;
if(tp!=-1)
ans=min(tp,ans);
if(ans==-1)ans=tp;
 b--;c++;
}while(ans==-1);


printf("%d\n",ans);
return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值