codeforces 1814 B. Long Legs

题意

可以选择在一回合中增长腿长 1,也可以选择在 x 轴或 y 轴增加当前腿长,问最少多少回合达到坐标 (a,b)

思路

首先容易想到升级的顺序是无关的,即你可以达到一个腿长 x ,那么对于 a b,一定只需要 a/x + 1(if a % x != 0), b/x + 1(if b % x != 0)

但是 x 枚举多少呢?一开始看数据范围直觉感觉是枚举到 sqrt(max(a,b)) ,后来为wa

怀疑是三分,补了个三分还是wa

打表看了下,把sqrt(max(a,b)) 开 2 倍常数就能过

题解里说了 根据导数证明其实是 根号2 常数

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

int check(int a,int b,int tmp)
{
    if(tmp==0) return a + b;
    int cost = 0;
    if(a%tmp!=0) cost++;
    if(b%tmp!=0) cost++;
    return cost + (a / tmp) + (b / tmp);
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int a,b,ans;
        scanf("%d%d",&a,&b);
        ans = a + b;
        for(int i = 1;i<=sqrt(a)*sqrt(2)+1;++i)
        {
                ans = min(ans,check(a,b,i)+i-1) ;
                if(a/i>=1) ans = min(ans,check(a,b,a/i)+a/i-1);
        }

        for(int i = 1;i<=sqrt(b)*sqrt(2)+1;++i)
        {

                ans = min(ans,check(a,b,i)+i-1);
                if(b/i>=1) ans = min(ans,check(a,b,b/i)+b/i-1);
        }
//        int l = 1, r = max(a,b);
//        while(l<=r)
//        {
//            int init_l = l, init_r = r;
//            int m1 = l + (r-l) / 3;
//            int m2 = r - (r-l) / 3;
//            ans = min(ans,check(a,b,m1)+m1-1);
//            ans = min(ans,check(a,b,m2)+m2-1);
//            if(check(a,b,m1)+m1-1 > check(a,b,m2)+m2-1) l = m1;
//            else r = m2;
//            if(l==init_l && r == init_r) break;
//        }
//        for(int i = l;i<=r;++i) ans = min(ans,check(a,b,i)+i-1);
        printf("%d\n",ans);
    }
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值