【腾讯云智笔试题——分苹果时间复杂度和空间复杂度都是O(1)】

题目描述

有m个苹果,n个小孩。每个小孩都有一个编号,小明的编号是。要尽量公平的分苹果,相邻编号的小孩分到的苹果数目差距不能大于1。
请问如何在满足相邻编号的小孩分到的苹果数目差距不能大于1的情况下,小明分配到的苹果数目最多,并且输出这个最大值,每个小朋友至少需分配到一个苹果。

输入描述
第一行输入三个整数。

输出描述
输出一行,表示小明分配到苹果个数的最大值。

示例 1
4 6 2
输出
2

说明

可以这样分配1 2 2 1。可以小明分配到了2个苹果。
图片:
原题图片

解题思路:

首先我这边有两种思路,第一种是暴力时间复杂度是O(m),即苹果越多,时间越长,空间复杂度是O(n),因为根据小孩数量声明的切片,具体的地址在https://blog.csdn.net/m0_64941684/article/details/139796892?spm=1001.2014.3001.5501,第二种是利用高中数学中通过计算公式得出范围,不同范围内的苹果数是多少,因为全部是计算,不需要for循环所以时间复杂段和空间复杂度都是O(1),

代码如下

package main

import (
	"fmt"
	"math"
	"os"
)

// maxApplesForXiaoming 使用贪心策略计算小明最多能分到的苹果数
func maxApplesForXiaoming(m, n, k int) int {
	// 初始化小明最多能分到的苹果数为1
	maxApples := 1

	// 如果只有一个小孩,直接返回所有苹果
	if n == 1 {
		return m
	}
	if m < n {
		return -1
	}

	m = m - n
	var big int
	var small int
	if (k - 1) > (n - k) {
		big = k - 1
		small = n - k
	} else {
		big = n - k
		small = k - 1
	}

	// 确定小明的位置相对于序列长度的位置
	// 计算从左到小明处能分配的苹果数(等差数列求和)
	bigSum := (big * (big + 1)) / 2

	smallSum := (small * (small + 1)) / 2
	totalEquidifference := bigSum + smallSum + small*(big-small) + big + 1

	smallEquidifference := smallSum*2 + small + 1
	switch true {
	case m > totalEquidifference:
		maxApples = big + 1 + (m-totalEquidifference)/n + 1
		return maxApples

	case m == totalEquidifference:
		maxApples = big + 1 + 1
		return maxApples

	case m < totalEquidifference && m > smallEquidifference:
		maxApples = small + int(math.Sqrt(float64(2*(m-smallEquidifference)+((3+2*small)/2)*(3+2*small)))) - (3+2*small)/2 + 1
		return maxApples
	case m == smallEquidifference:
		maxApples = small + 1
	case m < smallEquidifference:
		maxApples = int(math.Sqrt(float64(m))) - 1
		return maxApples + 1 + 1
	}

	return maxApples
}

func main() {
	var n, m, k int
	_, err := fmt.Scanln(&n, &m, &k)
	if err != nil {
		fmt.Println("Error reading input:", err)
		os.Exit(1)
	}
	result := maxApplesForXiaoming(m, n, k)
	if result != -1 {
		fmt.Printf("小明最多能分到的苹果数为: %d\n", result)
	} else {
		fmt.Println("无法满足每个小孩至少分到一个苹果的条件")
	}
}

思路讲解:

通过n,m,k(小孩数量,苹果数量,和编号)进行计算在不同情况下计算方式不同,
首先我们假设编号处于中间,两边可以为0(即k为1或者n),不影响计算,
然后我们定义一些值:

  1. big 两边大的一边的长度,左边大为左边,右边大为右边
  2. small 两边小的一边的长度,左边小为左边,右边小为右边
    3.bigSum 大的等差总和,即大的那一边从边界到k编号的等差综合,因为边长为big,所以bigSun = (big * (big + 1)) / 2
  3. smallSun大的等差总和,即小的那一边从边界到k编号的等差综合,因为边长为small,所以smallSun = (small* (small + 1)) / 2

了解这些值之后我们就可以确定一些边界啦

  1. 边界1:左右两边都是等差,因为相邻孩子苹果数相差不超过1,所以小边等差末尾一般不为1(除非大小边相等),那么这种情况下所需要的苹果数之和是:
    totalEquidifference := bigSum + smallSum + small*(big-small) + big + 1
    在这里插入图片描述

  2. 边界2:小边是从1开始的等差的情况,所以大边的情况应该是和小边情况一样,所以这种情况下所需要的苹果数之和是:
    smallEquidifference := smallSum*2 + small + 1
    详解如图:
    在这里插入图片描述

根据两个边界可以得出几种情况:

  1. 大于边界1
    小明的苹果数:maxApples = big + 1 + (m-totalEquidifference)/n + 1
    边界1时小明苹果数为big+1+1(后面的1是初始没人都有一个苹果),接下来每多n个苹果就每人加1,且只有第n个才是小明的,

  2. 等于边界1
    maxApples = big + 1 + 1
    边界1时小明苹果数为big+1+1(后面的1是初始没人都有一个苹果)

  3. 边界1与边界2之间
    maxApples = small + int(math.Sqrt(float64(2*(m-smallEquidifference)+((3+2*small)/2)*(3+2*small)))) - (3+2*small)/2 + 1
    在这里插入图片描述

  4. 等于边界2
    maxApples = small + 1
    边界2时小明苹果数为small+1+1(后面的1是初始没人都有一个苹果)
    10.小于边界2
    maxApples = int(math.Sqrt(float64(m))) - 1
    在这里插入图片描述
    整体过程可能有点复杂,但主要思路就是找到边界然后在根据边界划分不同区域,在同一区域内数据变化是一致的,即可以计算的,那么就可以根据边界判断适合那种公式,从而计算得出结果。

  • 16
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
首先,您需要在Spring Boot项目中添加创蓝云短信发送的依赖。在pom.xml文件中添加以下依赖项: ```xml <dependency> <groupId>com.cloopen</groupId> <artifactId>sms-api</artifactId> <version>1.0.0</version> </dependency> ``` 然后,您需要在application.properties或application.yml文件中配置创蓝云短信发送的相关参数,包括账号、密码、短信接口地址等。例如,在application.properties文件中添加以下配置: ```properties cloopen.accountSid=your_account_sid cloopen.authToken=your_auth_token cloopen.smsUrl=https://app.cloopen.com:8883/2013-12-26/Accounts/{accountSid}/SMS/TemplateSMS?sig={sigParameter} ``` 请将your_account_sid替换为您的创蓝云短信账号的Account Sid,将your_auth_token替换为您的创蓝云短信账号的Auth Token。 接下来,您可以编写一个发送短信的工具类,提供发送短信的方法。在该方法中,您可以使用创蓝云短信发送的API进行短信发送。以下是一个简单的示例: ```java import com.cloopen.rest.sdk.CCPRestSDK; public class SmsUtil { public static void sendSms(String to, String templateId, String[] datas) { // 创建CCPRestSDK对象 CCPRestSDK restAPI = new CCPRestSDK(); // 初始化REST SDK restAPI.init("app.cloopen.com", "8883"); restAPI.setAccount("your_accountSid", "your_authToken"); restAPI.setAppId("your_appId"); // 设置发送短信的参数 HashMap<String, Object> result = restAPI.sendTemplateSMS(to, templateId, datas); // 解析发送结果 if ("000000".equals(result.get("statusCode"))) { // 短信发送成功 System.out.println("短信发送成功!"); } else { // 短信发送失败 System.out.println("短信发送失败,错误码:" + result.get("statusCode")); } } } ``` 在sendSms方法中,您需要将to替换为目标手机号码,templateId替换为短信模板ID,datas替换为短信模板中的参数。 最后,您可以在Spring Boot的业务逻辑中调用该工具类的方法来发送短信。 以上是整合创蓝云短信发送的基本步骤,如果您还有其他问题,请继续提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值