首页 > 其他分享 >CF1814B. Long Legs 题解 枚举

CF1814B. Long Legs 题解 枚举

时间:2024-10-14 16:43:09浏览次数:6  
标签:lceil CF1814B 题解 机器人 加数 操作 frac Legs rceil

题目链接:https://codeforces.com/problemset/problem/1814/B

题目大意

有一个无限大的二维平面,我们用 \((x, y)\) 来表示平面中横坐标为 \(x\) 纵坐标为 \(y\) 的那个位置。

一个机器人被放置在该二维平面的 \((0, 0)\) 位置中。该机器人的腿长可以调节。最初,它的腿长为 \(1\) 。

假设机器人当前位于 \((x, y)\) 位置,其腿长为 \(m\) 。在一次移动中,它可以执行以下三个动作之一:

  • 跳到 \((x + m, y)\) 位置;
  • 跳到 \((x, y + m)\) 位置;
  • 将腿的长度增加 \(1\) ,即将其腿长设置为 \(m + 1\) 。

求:机器人到达 \((a, b)\) 位置格的最小移动次数是多少?

题解

首先,我们考虑最终(即机器人到达 \((a, b)\) 时)机器人的腿长。

我们设机器人最终的腿长为 \(k\)。

这也就是说,在整个过程中,经历了机器人的腿长为 \(1, 2, 3, \ldots, k\) 的所有时刻。

为了方便表述,我们将题目里提到的三种操作分别称为 操作1、操作2 和 操作3,即:

  • 操作1:跳到 \((x + m, y)\) 位置;
  • 操作2:跳到 \((x, y + m)\) 位置;
  • 操作3:将腿的长度增加 \(1\) ,即将其腿长设置为 \(m + 1\) 。

如果当前腿长为 \(m\),选择操作1,横坐标会增加 \(m\),选择操作2,纵坐标会增加 \(m\)。

我们可以将横坐标和纵坐标单独分析。

对于最终的横坐标 \(a\),在确定最终的腿长 \(k\) 的情况下,其实就是计算最少需要几个加数满足这些加数之和恰好为 \(a\),同时每个加数都不超过 \(k\)。很明显加数的数量最少为 \(\lceil \frac{a}{k} \rceil\) 个(这里 \(\lceil x \rceil\) 表示 \(x\) 向上取整)。

同理,我们可以得到,要按同样的方式得到 \(b\),加数的数量最少为 \(\lceil \frac{b}{k} \rceil\) 个。

这也就是说,在机器人最终的腿长为 \(k\) 的情况下:

  • 操作1会执行 \(\lceil \frac{a}{k} \rceil\) 次;
  • 操作2会执行 \(\lceil \frac{b}{k} \rceil\) 次;
  • 操作3会执行 \(k-1\) 次(腿长从 \(1\) 增加到 \(k\) 需要 \(k - 1\) 次操作3)。

总的操作次数为 \(\lceil \frac{a}{k} \rceil + \lceil \frac{b}{k} \rceil + (k - 1)\)。

所以我们可以枚举 \(k\),然后求 \(\lceil \frac{a}{k} \rceil + \lceil \frac{b}{k} \rceil + (k - 1)\) 的最小值,即为答案。

\(k\) 的上限取为 \(\max(a, b)\) 的话,总的时间复杂度是 \(O(t \max(a, b))\),会超时。

但是考虑到,当 \(k \gt \sqrt{a}\) 时,相加得到 \(a\) 所需的加数不会超过 \(\sqrt{a}\) 个,所以 \(k\) 超过 \(2 \sqrt{a}\) 肯定不是最优解了,我那其中一般的操作3改为操作1,就能让横坐标变为 \(a\) 了。

所以,只需从 \(1\) 到 \(\sqrt{ \max(a, b) }\) 去枚举 \(k\),然后求操作次数的最小值即可(代码实现时为了方便起见给 \(k\) 开到 \(10^5\),因为 \(10^5\) 肯定大于 \(\sqrt{ \max(a, b) }\),同时也不会超时,所以也是没有问题的)。

示例程序:

#include <bits/stdc++.h>
using namespace std;

int cal(int a, int b) {
    int res = a + b;
    for (int k = 2; k <= 1e5; k++) {
        int tmp = (k - 1) + (a - 1) / k + 1 + (b - 1) / k + 1;
        res = min(res, tmp);
    }
    return res;
}

int t, a, b;

int main() {
    cin >> t;
    while (t--) {
        cin >> a >> b;
        cout << cal(a, b) << endl;
    }
    return 0;
}

标签:lceil,CF1814B,题解,机器人,加数,操作,frac,Legs,rceil
From: https://www.cnblogs.com/quanjun/p/18464535

相关文章

  • 【题解】Solution Set - NOIP2024集训Day50 图的连通性相关
    【题解】SolutionSet-NOIP2024集训Day50图的连通性相关https://www.becoder.com.cn/contest/5618「JSOI2012」越狱老虎桥简述题意:题目大意:给定一张图,A先添加\(1\)条边,B再删去一条边使得图不连通,A要最大化删除边的权值,B要最小化删除边的权值,问最终的权值是多少。......
  • qoj8528 Chords 题解
    数据随机有什么用?用你惊人的注意力可以观察到答案的值域在\(800\)附近。考虑暴力dp,设\(dp_{l,r}\)表示值域在\([l,r]\)中最多能选几个区间。假设\(r\)对应区间的左端点为\(lst\),那么有转移方程\(dp_{l,r}=dp_{l,lst-1}+dp_{lst+1,r-1}+1\)。时间复杂度\(O(n^2)\)。......
  • Codeforces Round 978 (Div. 2) A-D1 题解
    我的同学还在VP,排名马上放声明:不要觉得有subtask的题目只做Easyversion没有意义,从这里也能捞很多分,况且有的时候并不是简单和难的区别,而是考不同的算法A.BustoPénjamo题意有一辆车上面有$r$排座位,每排有$2$个座位,现在共$n$个家庭出行坐公交车,每个家庭$a_i$......
  • 洛谷 P2071 座位安排题解
    因为一个人坐一个座位很像二分图,题意转化为二分图最大匹配。把人放在左部,把座位放在右部,一排座位占右部的两个点。假设人想要坐在\(x\)排,那么建图的时候就可以将这个人连向\(2x\)和\(2x+1\)。这样一排就对应着两个人了。由于\(n\le4000\),直接由朴素的\(O(nm)\)的匈牙利......
  • 【题解】CEIT 2024 第三周算法训练 讲义题解
    A.Orange的作文排版关于处理若干行输入,我们可以用while结合getline函数来完成,每次读取一行,就让行数+1,然后每次利用string的size方法得到当前行的列数,更新最长的列,最后得到答案。#include<bits/stdc++.h>usingnamespacestd;intmain(){strings;inta=0;i......
  • 01背包问题/Ieee全球极限编程大赛11.0题BeetleBag题解/洛谷P1926 小书童——刷题大军
    基础01背包问题概述给出一个容积为V的背包,有i个物体,每个物体都有自己的体积和价值,用Vi和Wi表示,要将这些物体装进背包里面,问怎样才能使得装入物体的总价值最大?最大为多少?解决思路1.如果你没能正确理解这道题,尤其是对于很多新手,第一反应可能是将所有物体的单位价值算出来,然后......
  • 带中位数写法的快速排序再讨论 & leetcode 215. Kth Largest Element in an Array题解
    带中位数写法的快速排序再讨论&leetcode215.KthLargestElementinanArray题解 探讨带中位数的写法本身classSolution{public:intfindKthLargest(std::vector<int>&nums,intk){returnfakeQuickSort(nums,k,0,nums.size()-1);}privat......
  • ABC375 (A~G) 题解
    也是补完整场了。(虽然只有一题要补A模拟。B模拟。C模拟。D模拟。EE-3TeamDivision还想了蛮久的。题意:有三个队伍,各有一些人,人有能力值,人可以换队伍。问三个队伍能力值相同最少需要让多少人交换队伍。人数\(\le100\),值域\(\le1500\)题目还是挺误导人的,如......
  • [JLOI2015] 有意义的字符串 题解
    看到这个\(7\times10^{18}\)的模数已经可以摆烂了。不是,你告诉我这东西跟矩阵快速幂优化DP有关系??观察到这个题显然不能硬做,因为你显然不能直接算小数部分,而且还有个取模很难受。所以我们希望把一切的计算都基于整数。这个时候我们就要思考,有什么东西可以把根号转化为整数......
  • Codeforces Round 899 (Div. 2)题解记录
    题目链接:https://codeforces.com/contest/1882A.IncreasingSequence从1开始慢慢和\(a[i]\)的所有值比较,注意最后一个位置特判下#include<iostream>#include<string.h>#include<map>#include<vector>#include<set>#include<unordered_set>#include<......