LeetCode 1954. 收集足够苹果的最小花园周长:数学O(1)的做法

2023-12-24 18:12

本文主要是介绍LeetCode 1954. 收集足够苹果的最小花园周长:数学O(1)的做法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

【LetMeFly】1954.收集足够苹果的最小花园周长:数学O(1)的做法

力扣题目链接:https://leetcode.cn/problems/minimum-garden-perimeter-to-collect-enough-apples/

给你一个用无限二维网格表示的花园,每一个 整数坐标处都有一棵苹果树。整数坐标 (i, j) 处的苹果树有 |i| + |j| 个苹果。

你将会买下正中心坐标是 (0, 0) 的一块 正方形土地 ,且每条边都与两条坐标轴之一平行。

给你一个整数 neededApples ,请你返回土地的 最小周长 ,使得 至少 有 neededApples 个苹果在土地 里面或者边缘上

|x| 的值定义为:

  • 如果 x >= 0 ,那么值为 x
  • 如果 x < 0 ,那么值为 -x

 

示例 1:

输入:neededApples = 1
输出:8
解释:边长长度为 1 的正方形不包含任何苹果。
但是边长为 2 的正方形包含 12 个苹果(如上图所示)。
周长为 2 * 4 = 8 。

示例 2:

输入:neededApples = 13
输出:16

示例 3:

输入:neededApples = 1000000000
输出:5040

 

提示:

  • 1 <= neededApples <= 1015

方法一:求公式

边长为 2 n 2n 2n的正方形,苹果数量为多少呢?

由于X和Y是相互独立的,因此二者可以分开来看。对于X:

边长为 2 n 2n 2n的正方形一共有 2 n + 1 2n+1 2n+1行,每行有Y轴左右共 2 2 2部分。只考虑其中一行Y轴右侧的部分:

对苹果的总贡献数为 0 + 1 + 2 + ⋯ + n = n ( n + 1 ) 2 0+1+2+\cdots+n=\frac{n(n+1)}{2} 0+1+2++n=2n(n+1)

因此所有的X的贡献为 ( 2 n + 1 ) × 2 × n ( n + 1 ) 2 = n ( n + 1 ) ( 2 n + 1 ) (2n+1)\times2\times\frac{n(n+1)}{2}=n(n+1)(2n+1) (2n+1)×2×2n(n+1)=n(n+1)(2n+1)

由于Y与X类似,所以Y的贡献与X相同,因此边长为2n的正方形的苹果数为 2 n ( n + 1 ) ( 2 n + 1 ) 2n(n+1)(2n+1) 2n(n+1)(2n+1)

n n n为多少才能至少有neededApples个苹果呢?

将上式处理一下: 2 n ( n + 1 ) ( 2 n + 1 ) = 4 n ( n + 1 ) ( n + 0.5 ) ≈ 4 n 3 2n(n+1)(2n+1)=4n(n+1)(n+0.5)\approx 4n^3 2n(n+1)(2n+1)=4n(n+1)(n+0.5)4n3并且大于 4 n 3 4n^3 4n3

也就是说要求的 n n n就在 1 4 n e e d e d A p p l e s 3 \sqrt[3]{\frac14neededApples} 341neededApples 附近。令 m = 1 4 n e e d e d A p p l e s 3 m=\sqrt[3]{\frac14neededApples} m=341neededApples ,其实从 ⌊ m ⌋ − 10 \lfloor m\rfloor - 10 m10 ⌊ m ⌋ + 10 \lfloor m\rfloor+10 m+10算一遍就直到答案了。

有没有更靠谱/可信一点的证明? (此部分可跳过)

n = ⌊ m ⌋ n=\lfloor m\rfloor n=m,令 f ( n ) = n ( n + 1 ) ( n + 0.5 ) f(n)=n(n+1)(n+0.5) f(n)=n(n+1)(n+0.5),则是在求最小的 n n n使得 f ( n ) ≥ 1 4 n e e d e d A p p l e s f(n)\geq \frac14neededApples f(n)41neededApples。因为有:

  1. f ( n − 1 ) = ( n − 1 ) n ( n − 0.5 ) < n 3 ≤ m 3 = 1 4 n e e d e d A p p l e s f(n-1)=(n-1)n(n-0.5)\lt n^3\leq m^3=\frac14neededApples f(n1)=(n1)n(n0.5)<n3m3=41neededApples,因此 n − 1 n-1 n1必定偏小
  2. f ( n + 1 ) = ( n + 1 ) ( n + 2 ) ( n + 1.5 ) > ( n + 1 ) 3 = ⌈ m ⌉ 3 > 1 4 n e e d e d A p p l e s f(n+1)=(n+1)(n+2)(n+1.5)\gt (n+1)^3=\lceil m\rceil^3\gt \frac14neededApples f(n+1)=(n+1)(n+2)(n+1.5)>(n+1)3=m3>41neededApples,因此 n + 1 n+1 n+1必定满足要求

所以答案 a n s ans ans的范围是: [ n , n + 1 ] [n, n+1] [n,n+1],其中 n = ⌊ m ⌋ = ⌊ 1 4 n e e d e d A p p l e s 3 ⌋ n=\lfloor m\rfloor=\lfloor \sqrt[3]{\frac14neededApples}\rfloor n=m=341neededApples

因此只需要先计算出 ⌊ 1 4 n e e d e d A p p l e s 3 ⌋ \lfloor \sqrt[3]{\frac14neededApples}\rfloor 341neededApples ,并在不满足要求(苹果数偏少)时不断加加一,直到满足要求即可。(最多会加1次一)

  • 时间复杂度 O ( 1 ) O(1) O(1),开立方根有内置库,可视为 O ( 1 ) O(1) O(1)时间复杂度
  • 空间复杂度 O ( 1 ) O(1) O(1)

AC代码

C++
/*
x: 2(2n+1)(1+2+...+n)=n(n+1)(2n+1)
y = x
x + y: 2n(n+1)(2n+1) = 4n(n+1)(n+0.5)≈4n^3
*/
class Solution {
public:long long minimumPerimeter(long long neededApples) {long long ans = cbrt((double)0.25 * neededApples);while (2 * ans * (ans + 1) * (2 * ans + 1) <  neededApples) {ans++;}return ans * 8;}
};
Python
# from numpy import cbrtclass Solution:def minimumPerimeter(self, neededApples: int) -> int:ans = int(cbrt(0.25 * neededApples))while 2 * ans * (ans + 1) * (2 * ans + 1) < neededApples:ans += 1return ans * 8

同步发文于CSDN,原创不易,转载经作者同意后请附上原文链接哦~
Tisfy:https://letmefly.blog.csdn.net/article/details/135183907

这篇关于LeetCode 1954. 收集足够苹果的最小花园周长:数学O(1)的做法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/532670

相关文章

使用C#代码计算数学表达式实例

《使用C#代码计算数学表达式实例》这段文字主要讲述了如何使用C#语言来计算数学表达式,该程序通过使用Dictionary保存变量,定义了运算符优先级,并实现了EvaluateExpression方法来... 目录C#代码计算数学表达式该方法很长,因此我将分段描述下面的代码片段显示了下一步以下代码显示该方法如

JS常用组件收集

收集了一些平时遇到的前端比较优秀的组件,方便以后开发的时候查找!!! 函数工具: Lodash 页面固定: stickUp、jQuery.Pin 轮播: unslider、swiper 开关: switch 复选框: icheck 气泡: grumble 隐藏元素: Headroom

哈希leetcode-1

目录 1前言 2.例题  2.1两数之和 2.2判断是否互为字符重排 2.3存在重复元素1 2.4存在重复元素2 2.5字母异位词分组 1前言 哈希表主要是适合于快速查找某个元素(O(1)) 当我们要频繁的查找某个元素,第一哈希表O(1),第二,二分O(log n) 一般可以分为语言自带的容器哈希和用数组模拟的简易哈希。 最简单的比如数组模拟字符存储,只要开26个c

poj 1258 Agri-Net(最小生成树模板代码)

感觉用这题来当模板更适合。 题意就是给你邻接矩阵求最小生成树啦。~ prim代码:效率很高。172k...0ms。 #include<stdio.h>#include<algorithm>using namespace std;const int MaxN = 101;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int n

poj 1287 Networking(prim or kruscal最小生成树)

题意给你点与点间距离,求最小生成树。 注意点是,两点之间可能有不同的路,输入的时候选择最小的,和之前有道最短路WA的题目类似。 prim代码: #include<stdio.h>const int MaxN = 51;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int P;int prim(){bool vis[MaxN];

poj 2349 Arctic Network uva 10369(prim or kruscal最小生成树)

题目很麻烦,因为不熟悉最小生成树的算法调试了好久。 感觉网上的题目解释都没说得很清楚,不适合新手。自己写一个。 题意:给你点的坐标,然后两点间可以有两种方式来通信:第一种是卫星通信,第二种是无线电通信。 卫星通信:任何两个有卫星频道的点间都可以直接建立连接,与点间的距离无关; 无线电通信:两个点之间的距离不能超过D,无线电收发器的功率越大,D越大,越昂贵。 计算无线电收发器D

uva 10014 Simple calculations(数学推导)

直接按照题意来推导最后的结果就行了。 开始的时候只做到了第一个推导,第二次没有继续下去。 代码: #include<stdio.h>int main(){int T, n, i;double a, aa, sum, temp, ans;scanf("%d", &T);while(T--){scanf("%d", &n);scanf("%lf", &first);scanf

uva 10025 The ? 1 ? 2 ? ... ? n = k problem(数学)

题意是    ?  1  ?  2  ?  ...  ?  n = k 式子中给k,? 处可以填 + 也可以填 - ,问最小满足条件的n。 e.g k = 12  - 1 + 2 + 3 + 4 + 5 + 6 - 7 = 12 with n = 7。 先给证明,令 S(n) = 1 + 2 + 3 + 4 + 5 + .... + n 暴搜n,搜出当 S(n) >=

uva 11044 Searching for Nessy(小学数学)

题意是给出一个n*m的格子,求出里面有多少个不重合的九宫格。 (rows / 3) * (columns / 3) K.o 代码: #include <stdio.h>int main(){int ncase;scanf("%d", &ncase);while (ncase--){int rows, columns;scanf("%d%d", &rows, &col

poj 1734 (floyd求最小环并打印路径)

题意: 求图中的一个最小环,并打印路径。 解析: ans 保存最小环长度。 一直wa,最后终于找到原因,inf开太大爆掉了。。。 虽然0x3f3f3f3f用memset好用,但是还是有局限性。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#incl