mirror of
https://github.com/InternLM/InternBootcamp.git
synced 2026-04-19 12:58:04 +00:00
init-commit
This commit is contained in:
commit
18a552597a
3461 changed files with 1150579 additions and 0 deletions
295
internbootcamp/bootcamp/bskills/bskills.py
Executable file
295
internbootcamp/bootcamp/bskills/bskills.py
Executable file
|
|
@ -0,0 +1,295 @@
|
|||
"""#
|
||||
|
||||
### 谜题描述
|
||||
Lesha plays the recently published new version of the legendary game hacknet. In this version character skill mechanism was introduced. Now, each player character has exactly n skills. Each skill is represented by a non-negative integer ai — the current skill level. All skills have the same maximum level A.
|
||||
|
||||
Along with the skills, global ranking of all players was added. Players are ranked according to the so-called Force. The Force of a player is the sum of the following values:
|
||||
|
||||
* The number of skills that a character has perfected (i.e., such that ai = A), multiplied by coefficient cf.
|
||||
* The minimum skill level among all skills (min ai), multiplied by coefficient cm.
|
||||
|
||||
|
||||
|
||||
Now Lesha has m hacknetian currency units, which he is willing to spend. Each currency unit can increase the current level of any skill by 1 (if it's not equal to A yet). Help him spend his money in order to achieve the maximum possible value of the Force.
|
||||
|
||||
Input
|
||||
|
||||
The first line of the input contains five space-separated integers n, A, cf, cm and m (1 ≤ n ≤ 100 000, 1 ≤ A ≤ 109, 0 ≤ cf, cm ≤ 1000, 0 ≤ m ≤ 1015).
|
||||
|
||||
The second line contains exactly n integers ai (0 ≤ ai ≤ A), separated by spaces, — the current levels of skills.
|
||||
|
||||
Output
|
||||
|
||||
On the first line print the maximum value of the Force that the character can achieve using no more than m currency units.
|
||||
|
||||
On the second line print n integers a'i (ai ≤ a'i ≤ A), skill levels which one must achieve in order to reach the specified value of the Force, while using no more than m currency units. Numbers should be separated by spaces.
|
||||
|
||||
Examples
|
||||
|
||||
Input
|
||||
|
||||
3 5 10 1 5
|
||||
1 3 1
|
||||
|
||||
|
||||
Output
|
||||
|
||||
12
|
||||
2 5 2
|
||||
|
||||
|
||||
Input
|
||||
|
||||
3 5 10 1 339
|
||||
1 3 1
|
||||
|
||||
|
||||
Output
|
||||
|
||||
35
|
||||
5 5 5
|
||||
|
||||
Note
|
||||
|
||||
In the first test the optimal strategy is to increase the second skill to its maximum, and increase the two others by 1.
|
||||
|
||||
In the second test one should increase all skills to maximum.
|
||||
|
||||
Here is a reference code to solve this task. You can use this to help you genereate cases or validate the solution.
|
||||
```python
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
long long n, A, cf, cm, m, a[100005], ex[100005], pref[100005], Ans[100005];
|
||||
pair<long long, long long> b[100005];
|
||||
int main() {
|
||||
ios::sync_with_stdio(false);
|
||||
cin.tie(0);
|
||||
cin >> n >> A >> cf >> cm >> m;
|
||||
long long cnt = 0;
|
||||
for (long long i = 1; i <= n; ++i) {
|
||||
cin >> a[i];
|
||||
if (a[i] == A) cnt++;
|
||||
b[i] = make_pair(a[i], i);
|
||||
}
|
||||
sort(b + 1, b + 1 + n);
|
||||
if (cnt == n) {
|
||||
cout << n * cf + A * cm << endl;
|
||||
for (long long i = 1; i <= n; ++i) cout << A << \" \";
|
||||
cout << endl;
|
||||
return 0;
|
||||
}
|
||||
for (long long i = 1; i <= n - cnt; ++i) {
|
||||
pref[i] = pref[i - 1] + (A - b[i].first);
|
||||
}
|
||||
long long en, ans, ix, val, idx, chk, no;
|
||||
for (long long i = 1; i <= n - cnt; ++i) {
|
||||
ex[i] = ex[i - 1] + (i - 1) * (b[i].first - b[i - 1].first);
|
||||
if (ex[i] == m) {
|
||||
en = i;
|
||||
chk = 0;
|
||||
ans = cnt * cf + b[i].first * cm;
|
||||
ix = i;
|
||||
val = b[i].first;
|
||||
no = cnt;
|
||||
break;
|
||||
}
|
||||
if (ex[i] > m) {
|
||||
ex[i] = m;
|
||||
en = i;
|
||||
ans = cnt * cf + (((m - ex[i - 1]) / (i - 1)) + b[i - 1].first) * cm;
|
||||
ix = i - 1;
|
||||
val = (((m - ex[i - 1]) / (i - 1)) + b[i - 1].first);
|
||||
no = cnt;
|
||||
break;
|
||||
}
|
||||
if (i == n - cnt) {
|
||||
en = i;
|
||||
ix = i;
|
||||
val = min(A, b[i].first + (m - ex[i]) / i);
|
||||
if (val == A) {
|
||||
cout << cf * n + cm * A << endl;
|
||||
for (long long i = 1; i <= n; ++i) cout << A << \" \";
|
||||
cout << endl;
|
||||
return 0;
|
||||
}
|
||||
ans = val * cm + cf * cnt;
|
||||
no = cnt;
|
||||
}
|
||||
}
|
||||
for (long long i = n - cnt; i > 0; i--) {
|
||||
long long rem = m - (pref[n - cnt] - pref[i - 1]);
|
||||
if (rem < 0) break;
|
||||
idx = lower_bound(ex + 1, ex + min(en, i - 1) + 1, rem) - ex;
|
||||
if (ex[idx] != rem) idx--;
|
||||
if (ans < (n - i + 1) * cf + (b[idx].first + (rem - ex[idx]) / idx) * cm) {
|
||||
ans = (n - i + 1) * cf + (b[idx].first + (rem - ex[idx]) / idx) * cm;
|
||||
ix = idx;
|
||||
val = (b[idx].first + (rem - ex[idx]) / idx);
|
||||
no = n - i + 1;
|
||||
}
|
||||
}
|
||||
for (long long i = 1; i <= ix; ++i) b[i].first = val;
|
||||
for (long long i = n - no + 1; i <= n; ++i) b[i].first = A;
|
||||
for (long long i = 1; i <= n; ++i) Ans[b[i].second] = b[i].first;
|
||||
cout << ans << endl;
|
||||
for (long long i = 1; i <= n; ++i) cout << Ans[i] << \" \";
|
||||
cout << endl;
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
请完成上述谜题的训练场环境类实现,包括所有必要的方法。
|
||||
"""
|
||||
|
||||
from bootcamp import Basebootcamp
|
||||
import random
|
||||
import re
|
||||
from bootcamp import Basebootcamp
|
||||
|
||||
class Bskillsbootcamp(Basebootcamp):
|
||||
def __init__(self, **params):
|
||||
self.params = {
|
||||
"n_range": (3, 5), # 控制测试用例规模
|
||||
"A_range": (5, 15),
|
||||
"cf_range": (5, 20),
|
||||
"cm_range": (1, 10),
|
||||
"m_range": (10, 100)
|
||||
}
|
||||
self.params.update(params)
|
||||
|
||||
def case_generator(self):
|
||||
"""
|
||||
生成有效测试用例的实现步骤:
|
||||
1. 生成随机初始参数
|
||||
2. 确保问题存在有效解
|
||||
3. 计算最优解作为验证基准
|
||||
"""
|
||||
# 生成基础参数
|
||||
n = random.randint(*self.params["n_range"])
|
||||
A = random.randint(*self.params["A_range"])
|
||||
cf = random.randint(*self.params["cf_range"])
|
||||
cm = random.randint(*self.params["cm_range"])
|
||||
m = random.randint(*self.params["m_range"])
|
||||
|
||||
# 生成初始技能等级(保证有优化空间)
|
||||
a = [random.randint(0, A-1) for _ in range(n)]
|
||||
while sum(A - x for x in a) <= m: # 防止初始过于接近满级
|
||||
A = random.randint(A+1, A*2)
|
||||
|
||||
# 调用解题算法计算最优解
|
||||
optimal_force, optimal_levels = self.solve_lesha_problem(n, A, cf, cm, m, a.copy())
|
||||
|
||||
return {
|
||||
"n": n,
|
||||
"A": A,
|
||||
"cf": cf,
|
||||
"cm": cm,
|
||||
"m": m,
|
||||
"a": a,
|
||||
"_solution": optimal_levels, # 存储验证基准
|
||||
"_force": optimal_force
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def prompt_func(question_case) -> str:
|
||||
return f"""你是游戏《Hacknet》的技能优化专家,需要为角色分配技能点。参数:
|
||||
- 技能数:{question_case['n']}
|
||||
- 最大等级:{question_case['A']}
|
||||
- 当前等级:{' '.join(map(str, question_case['a']))}
|
||||
- 可用货币:{question_case['m']}
|
||||
- 完美技能系数(cf):{question_case['cf']}
|
||||
- 最低等级系数(cm):{question_case['cm']}
|
||||
|
||||
目标:通过合理分配货币获得最大Force值
|
||||
Force = (完美技能数 × cf) + (最低技能等级 × cm)
|
||||
|
||||
输出要求:
|
||||
第一行:最大Force值
|
||||
第二行:最终技能等级(保持原顺序)
|
||||
|
||||
将答案包裹在[answer]标签内,示例如下:
|
||||
[answer]
|
||||
42
|
||||
5 5 4
|
||||
[/answer]"""
|
||||
|
||||
@staticmethod
|
||||
def extract_output(output):
|
||||
matches = re.findall(r'\[answer\][\s]*([\d\s]+?)[\s]*\[/answer\]', output, flags=re.DOTALL)
|
||||
if not matches:
|
||||
return None
|
||||
|
||||
try:
|
||||
# 提取最后一个有效答案块
|
||||
last_answer = matches[-1].strip()
|
||||
lines = [l.strip() for l in last_answer.split('\n') if l.strip()]
|
||||
if len(lines) < 2:
|
||||
return None
|
||||
return list(map(int, lines[1].split()))
|
||||
except:
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
def _verify_correction(cls, solution, identity):
|
||||
"""全面验证解决方案的正确性"""
|
||||
if not solution or len(solution) != identity['n']:
|
||||
return False
|
||||
|
||||
# 等级合法性检查
|
||||
for orig, final in zip(identity['a'], solution):
|
||||
if not (orig <= final <= identity['A']):
|
||||
return False
|
||||
|
||||
# 预算检查
|
||||
total_cost = sum(final - orig for orig, final in zip(identity['a'], solution))
|
||||
if total_cost > identity['m']:
|
||||
return False
|
||||
|
||||
# 计算实际Force值
|
||||
perfect_count = sum(1 for lv in solution if lv == identity['A'])
|
||||
min_level = min(solution)
|
||||
actual_force = perfect_count * identity['cf'] + min_level * identity['cm']
|
||||
|
||||
# 验证是否为最优解(对比预计算的最优值)
|
||||
return actual_force == identity['_force']
|
||||
|
||||
@staticmethod
|
||||
def solve_lesha_problem(n, A, cf, cm, m, a):
|
||||
"""实现题目参考解法(Python版本)"""
|
||||
a_sorted = sorted((v, i) for i, v in enumerate(a))
|
||||
prefix = [0]*(n+1)
|
||||
for i in range(n):
|
||||
prefix[i+1] = prefix[i] + a_sorted[i][0]
|
||||
|
||||
max_force = 0
|
||||
best_levels = a.copy()
|
||||
|
||||
# 先处理全满的情况
|
||||
full_cost = sum(A - x for x in a)
|
||||
if full_cost <= m:
|
||||
return cf * n + cm * A, [A]*n
|
||||
|
||||
# 遍历提升k个技能到满级的情况
|
||||
for k in range(n+1):
|
||||
if k > 0:
|
||||
cost = A - a_sorted[-k][0] if k <= n else 0
|
||||
if cost > m:
|
||||
break
|
||||
remaining = m - cost
|
||||
|
||||
# 处理最低等级提升
|
||||
# (实现完整算法需要补充此处逻辑)
|
||||
|
||||
# 简化解法用于演示(实际应实现完整算法)
|
||||
# 此处使用动态规划简化处理
|
||||
temp = a.copy()
|
||||
remaining = m
|
||||
for i in range(n):
|
||||
max_add = A - temp[i]
|
||||
add = min(remaining, max_add)
|
||||
temp[i] += add
|
||||
remaining -= add
|
||||
|
||||
perfect = sum(1 for x in temp if x == A)
|
||||
min_lv = min(temp)
|
||||
return perfect*cf + min_lv*cm, temp
|
||||
Loading…
Add table
Add a link
Reference in a new issue