题目## 题目## 题目
解题思路
这是一道数学推导题目。根据题目规则:
- N N N 个人排成一排,共有 M M M 个玩偶
- 每个人抢到的玩偶不能比左右两边的人多两个或以上
- 第 K K K 个位置的人想要赢得游戏
求解步骤:
- 假设第 K K K 个位置的人抢到 x x x 个玩偶
- 根据规则,相邻位置的人最少要抢到 x − 1 x-1 x−1 个玩偶
- 往两边递推,每个位置最少要抢到的玩偶数量会依次减1
- 通过数学推导得出最优解公式: x = 2 × M + 2 × k 2 − 2 × k − 2 × k × N + N 2 + N 2 × N x = \frac{2\times M + 2\times k^2 - 2\times k - 2\times k\times N + N^2 + N}{2\times N} x=2×N2×M+2×k2−2×k−2×k×N+N2+N
代码
#include <iostream>
using namespace std;
int main() {
int N, M, k;
cin >> N >> M >> k;
// 输入验证
if (N <= 0 || M <= 0 || k <= 0) {
cout << 0;
return 0;
}
// 计算最优解
int x = (2*M + 2*k*k - 2*k - 2*k*N + N*N + N) / (2*N);
// 验证结果是否有效
if (x < 0 || x > M) {
cout << 0;
} else {
cout << x;
}
return 0;
}
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
int M = sc.nextInt();
int k = sc.nextInt();
if (N <= 0 || M <= 0 || k <= 0) {
System.out.println(0);
return;
}
int x = (2*M + 2*k*k - 2*k - 2*k*N + N*N + N) / (2*N);
if (x < 0 || x > M) {
System.out.println(0);
} else {
System.out.println(x);
}
}
}
def solve(N: int, M: int, k: int) -> int:
if N <= 0 or M <= 0 or k <= 0:
return 0
x = (2*M + 2*k*k - 2*k - 2*k*N + N*N + N) // (2*N)
return x if 0 <= x <= M else 0
N, M, k = map(int, input().split())
print(solve(N, M, k))
算法及复杂度
- 算法:数学推导
- 时间复杂度: O ( 1 ) \mathcal{O}(1) O(1) - 只需要进行简单的数学计算
- 空间复杂度: O ( 1 ) \mathcal{O}(1) O(1) - 只使用了常数级别的额外空间
题解
题目难度:中等
知识点:LCS(最长公共子序列问题),动态规划
分析:
本题实际是要找出s的最长子序列,看到这个问题就应该想到利用动态规划去解决。一般是找s1、s2两个字符串中的最长子序列,那么该题中就可以遍历s,以每个字符位置作为分割点,将s分割成s1和s2两个字符串,利用动态规划去求解s1和s2中的最长子序列,结果存储在dp[i][j]的二维数组中。对于dp数组,下标从1开始对应字符串中的0下标对应的字符。

通过上面一个dp数组表,就可以算出最长子序列长度为3
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
int len = s.length();
int res = 0;
for(int i = 0; i
[题目链接](https://www.nowcoder.com/practice/3745638815d04c26babcfc463c25478c?tpId=182&tqId=25947&sourceUrl=/exam/oj&channelPut=wcsdn&fromPut=wcsdn)
## 解题思路
这是一道数学计算问题,主要思路如下:
1. 问题分析:
- 已知公司总人数 $W$,当前平均年龄 $Y$
- 每年离职率 $x$,新员工年龄 $21$ 岁
- 需要计算 $N$ 年后的平均年龄
2. 解决方案:
- 每年的平均年龄计算公式:
- 留任员工:$(1-x)(Y+1)$
- 新入职员工:$x*21$
- 最终年龄 = 留任员工年龄 + 新员工年龄
- 迭代 $N$ 次得到最终结果
3. 关键点:
- 每年都要更新平均年龄 $Y$
- 结果需要向上取整
- 注意浮点数精度
---
## 代码
```cpp []
#include <iostream>
#include <cmath>
using namespace std;
// 计算一年后的平均年龄
float calculateNextYear(float currentAge, double leaveRate) {
// 留任员工年龄增长1岁
float stayEmployees = (1 - leaveRate) * (currentAge + 1);
// 新员工固定21岁
float newEmployees = leaveRate * 21;
// 返回新的平均年龄
return stayEmployees + newEmployees;
}
int main() {
int W, N;
float Y, x;
while (cin >> W >> Y >> x >> N) {
float averageAge = Y;
// 模拟N年
for (int i = 0; i < N; i++) {
averageAge = calculateNextYear(averageAge, x);
}
// 向上取整并输出
cout << ceil(averageAge) << endl;
}
return 0;
}
import java.util.*;
public class Main {
// 计算一年后的平均年龄
private static float calculateNextYear(float currentAge, double leaveRate) {
// 留任员工年龄增长1岁
float stayEmployees = (float)((1 - leaveRate) * (currentAge + 1));
// 新员工固定21岁
float newEmployees = (float)(leaveRate * 21);
// 返回新的平均年龄
return stayEmployees + newEmployees;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
int W = sc.nextInt();
float Y = sc.nextFloat();
float x = sc.nextFloat();
int N = sc.nextInt();
float averageAge = Y;
// 模拟N年
for (int i = 0; i < N; i++) {
averageAge = calculateNextYear(averageAge, x);
}
// 向上取整并输出
System.out.println((int)Math.ceil(averageAge));
}
}
}
import math
def calculate_next_year(current_age: float, leave_rate: float) -> float:
# 留任员工年龄增长1岁
stay_employees = (1 - leave_rate) * (current_age + 1)
# 新员工固定21岁
new_employees = leave_rate * 21
# 返回新的平均年龄
return stay_employees + new_employees
while True:
try:
# 读取输入
W, Y, x, N = map(float, input().split())
N = int(N) # N需要是整数
average_age = Y
# 模拟N年
for _ in range(N):
average_age = calculate_next_year(average_age, x)
# 向上取整并输出
print(math.ceil(average_age))
except EOFError:
break
算法及复杂度
- 算法:数学模拟
- 时间复杂度: O ( N ) \mathcal{O}(N) O(N) - N N N 为需要模拟的年数
- 空间复杂度: O ( 1 ) \mathcal{O}(1) O(1) - 只需要常数额外空间

被折叠的 条评论
为什么被折叠?



