InternBootcamp/internbootcamp/bootcamp/bandreyandproblem/bandreyandproblem.py
2025-05-23 15:27:15 +08:00

144 lines
4.3 KiB
Python
Executable file
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""#
### 谜题描述
Andrey needs one more problem to conduct a programming contest. He has n friends who are always willing to help. He can ask some of them to come up with a contest problem. Andrey knows one value for each of his fiends — the probability that this friend will come up with a problem if Andrey asks him.
Help Andrey choose people to ask. As he needs only one problem, Andrey is going to be really upset if no one comes up with a problem or if he gets more than one problem from his friends. You need to choose such a set of people that maximizes the chances of Andrey not getting upset.
Input
The first line contains a single integer n (1 ≤ n ≤ 100) — the number of Andrey's friends. The second line contains n real numbers pi (0.0 ≤ pi ≤ 1.0) — the probability that the i-th friend can come up with a problem. The probabilities are given with at most 6 digits after decimal point.
Output
Print a single real number — the probability that Andrey won't get upset at the optimal choice of friends. The answer will be considered valid if it differs from the correct one by at most 10 - 9.
Examples
Input
4
0.1 0.2 0.3 0.8
Output
0.800000000000
Input
2
0.1 0.2
Output
0.260000000000
Note
In the first sample the best strategy for Andrey is to ask only one of his friends, the most reliable one.
In the second sample the best strategy for Andrey is to ask all of his friends to come up with a problem. Then the probability that he will get exactly one problem is 0.1·0.8 + 0.9·0.2 = 0.26.
Here is a reference code to solve this task. You can use this to help you genereate cases or validate the solution.
```python
m, y, n = input(), 0.0, 1.0
for p in sorted(map(float, raw_input().split()))[::-1]:
t = n*p + (1-p)*y
if t > y: y, n = t, n*(1-p)
print \"%.9f\" % y
```
请完成上述谜题的训练场环境类实现,包括所有必要的方法。
"""
from bootcamp import Basebootcamp
from bootcamp import Basebootcamp
import random
import re
class Bandreyandproblembootcamp(Basebootcamp):
def __init__(self, min_n=1, max_n=100):
self.min_n = min_n
self.max_n = max_n
def case_generator(self):
n = random.randint(self.min_n, self.max_n)
probs = [round(random.uniform(0, 1), 6) for _ in range(n)]
sorted_probs = sorted(probs, reverse=True)
optimal = 0.0
none_fail = 1.0
for p in sorted_probs:
candidate = none_fail * p + (1 - p) * optimal
if candidate > optimal:
optimal = candidate
none_fail *= (1 - p)
return {
"n": n,
"probabilities": probs,
"expected": optimal
}
@staticmethod
def prompt_func(question_case) -> str:
probs_str = ' '.join(f"{p:.6f}" for p in question_case["probabilities"])
return f"""你是安德烈,需要选择一组朋友来最大化恰好得到一个问题的概率。请根据输入数据计算最大概率。
规则:
1. 选择任意数量的朋友,每个被选中的朋友独立以给定概率成功
2. 只有当恰好一个朋友成功时,安德烈不会生气
3. 需要选择最优的朋友组合使成功概率最大
输入格式:
第一行为整数n朋友数量
第二行是n个实数保留6位小数
示例输入1
4
0.1 0.2 0.3 0.8
示例输出1
0.800000000000
示例输入2
2
0.1 0.2
示例输出2
0.260000000000
当前问题:
输入:
{question_case['n']}
{probs_str}
请输出最大概率必须包含至少9位小数并将最终答案放在[answer]和[/answer]之间。例如:[answer]0.260000000000[/answer]"""
@staticmethod
def extract_output(output):
matches = re.findall(r'\[answer\](.*?)\[/answer\]', output, re.DOTALL)
if not matches:
return None
last_match = matches[-1].strip()
try:
# 处理科学计数法和多余字符
cleaned = last_match.strip().rstrip('.').replace(',', '')
return float(cleaned)
except ValueError:
return None
@classmethod
def _verify_correction(cls, solution, identity):
if solution is None:
return False
try:
sol = float(solution)
expected = identity["expected"]
return abs(sol - expected) <= 1e-9
except:
return False