蓝桥杯备赛:农夫约翰真的种地(编程加数学不等式,真好玩)

只听课不思考不记笔记==假把式

 这道题目乍一看上去很难,但如果细细分析就会发现这道题目其实不是特别难,主要是用到了数学的不等式很多人想不到

1.题目拆解

 题目里面有一个特别难用的一个点,就是它说的ti的点,但是细细想想就会明白其中的奥秘。

 那这句话转意过来就是,对于第i个芦笋最终前面有i个芦笋,那再进一步想就是最终第i个芦笋排在第i+1个位置。

那么其实我们就可以根据这个数组对我们的第一个的数组进行重新排列,我们可以把重新排列后的数组叫做rk,同时我们也要对我们的ak进行二次排列,我们可以叫它ak,那么我们就可以列出不等式。

 2.解题思路

那么其实题目叫我们求的就是我们的x最小应该取多少,那么这个时候我们可以随便拿出一个式子进行化简

然后我们再分情况进行讨论

 

 接着我们再巧用数学里面的一个转化式子

 这个可以大家自己举个例子试试都是成立的,大家以后可以把这个式子记住,遇到的时候用就行

那么我们这道题目最终求的就是在这个区间里面,x所能取的最小值。 

3.优化 

对于上面我们要二次排列的方式,显然是非常麻烦的,我们可以用一个数组去存每个每个位置最终的对应原位置,这样我们的代码就简单很多了。

同时我们如果直接列不等式显然代码太长可读性也比较差,我们可以这样。

 

 这样就可以让我们的代码更好维护

#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;
const int N=200010;
int h[N],a[N],rk[N];
int main()
{
    int cnt,n;
    cin>>cnt;
    while(cnt--)
    {
        cin>>n;
        for(int i=0;i<n;i++)cin>>h[i];
        for(int i=0;i<n;i++)cin>>a[i];
        for(int i=0;i<n;i++){
            int tmp;
            cin>>tmp;
            rk[tmp]=i;
        }
        int l=0,r=1e9;
        for(int i=0;i<n-1;i++)//遍历每个不等式
        {
          int A=h[rk[i+1]]-h[rk[i]];
          int B=a[rk[i]]-a[rk[i+1]];
          if(B>0)
             l=max((int)floor((double)A/B)+1,l);//x>=
          else if(B<0)
            r=min((int)ceil((double)A/B)-1,r);//x<=
          else if(A>=0)
          {
                r=-1;
                break;
          }
         }
        if(l>r)l=-1;
        cout<<l<<endl;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱编程的小赵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值