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
229
internbootcamp/bootcamp/dsetofpoints/dsetofpoints.py
Executable file
229
internbootcamp/bootcamp/dsetofpoints/dsetofpoints.py
Executable file
|
|
@ -0,0 +1,229 @@
|
|||
"""#
|
||||
|
||||
### 谜题描述
|
||||
Convexity of a set of points on the plane is the size of the largest subset of points that form a convex polygon. Your task is to build a set of n points with the convexity of exactly m. Your set of points should not contain three points that lie on a straight line.
|
||||
|
||||
Input
|
||||
|
||||
The single line contains two integers n and m (3 ≤ m ≤ 100, m ≤ n ≤ 2m).
|
||||
|
||||
Output
|
||||
|
||||
If there is no solution, print \"-1\". Otherwise, print n pairs of integers — the coordinates of points of any set with the convexity of m. The coordinates shouldn't exceed 108 in their absolute value.
|
||||
|
||||
Examples
|
||||
|
||||
Input
|
||||
|
||||
4 3
|
||||
|
||||
|
||||
Output
|
||||
|
||||
0 0
|
||||
3 0
|
||||
0 3
|
||||
1 1
|
||||
|
||||
|
||||
Input
|
||||
|
||||
6 3
|
||||
|
||||
|
||||
Output
|
||||
|
||||
-1
|
||||
|
||||
|
||||
Input
|
||||
|
||||
6 6
|
||||
|
||||
|
||||
Output
|
||||
|
||||
10 0
|
||||
-10 0
|
||||
10 1
|
||||
9 1
|
||||
9 -1
|
||||
0 -2
|
||||
|
||||
|
||||
Input
|
||||
|
||||
7 4
|
||||
|
||||
|
||||
Output
|
||||
|
||||
176166 6377
|
||||
709276 539564
|
||||
654734 174109
|
||||
910147 434207
|
||||
790497 366519
|
||||
606663 21061
|
||||
859328 886001
|
||||
|
||||
Here is a reference code to solve this task. You can use this to help you genereate cases or validate the solution.
|
||||
```python
|
||||
n,m=map(int,raw_input().split())
|
||||
print -1 if 3==m and n>4 else '\n'.join(map(lambda x:'%d %d'%x,[(i,i*i) for i in range(m)]+[(i*i+10001,i) for i in range(n-m)]))
|
||||
```
|
||||
|
||||
|
||||
请完成上述谜题的训练场环境类实现,包括所有必要的方法。
|
||||
"""
|
||||
|
||||
from bootcamp import Basebootcamp
|
||||
import re
|
||||
import random
|
||||
from bootcamp import Basebootcamp
|
||||
|
||||
class Dsetofpointsbootcamp(Basebootcamp):
|
||||
def __init__(self, m_min=3, m_max=100, max_coordinate=10**8):
|
||||
super().__init__()
|
||||
self.m_min = max(m_min, 3) # 确保最小m值符合题目要求
|
||||
self.m_max = min(m_max, 100)
|
||||
self.max_coordinate = max_coordinate
|
||||
|
||||
def case_generator(self):
|
||||
while True:
|
||||
m = random.randint(self.m_min, self.m_max)
|
||||
max_possible_n = min(2 * m, 100) # 根据题目约束n ≤ 2m
|
||||
|
||||
# 生成合法n的范围
|
||||
if m == 3:
|
||||
# 允许生成无效案例(n>4)
|
||||
n = random.choice([
|
||||
random.randint(3, 4), # 有效案例
|
||||
random.randint(5, max_possible_n) # 无效案例
|
||||
])
|
||||
else:
|
||||
n = random.randint(m, max_possible_n)
|
||||
|
||||
# 确保20%概率生成边界案例
|
||||
if random.random() < 0.2:
|
||||
if m == 3:
|
||||
n = 5 # 强制无效案例
|
||||
else:
|
||||
n = 2 * m # 最大边界案例
|
||||
|
||||
return {"n": n, "m": m}
|
||||
|
||||
@staticmethod
|
||||
def prompt_func(question_case) -> str:
|
||||
n = question_case["n"]
|
||||
m = question_case["m"]
|
||||
example = ""
|
||||
if m == 3 and n == 4:
|
||||
example = "\n例如当n=4, m=3时,有效解可能是:\n0 0\n3 0\n0 3\n1 1"
|
||||
elif m == 6 and n == 6:
|
||||
example = "\n例如当n=6, m=6时,有效解可能是:\n10 0\n-10 0\n10 1\n9 1\n9 -1\n0 -2"
|
||||
|
||||
prompt = f"""## 平面点集凸度构造问题
|
||||
|
||||
### 问题描述
|
||||
给定两个整数n和m,需要构造一个包含n个点的集合,使得:
|
||||
1. 集合的凸度(最大凸多边形顶点数)恰好为m
|
||||
2. 集合中任意三点不共线
|
||||
3. 所有点坐标绝对值不超过1e8
|
||||
|
||||
### 输入参数
|
||||
- n = {n}
|
||||
- m = {m}
|
||||
|
||||
### 输出要求
|
||||
{'- 当且仅当m=3且n>4时输出-1' if m ==3 else ''}
|
||||
- 输出{n}个点的坐标,每行两个整数
|
||||
- 坐标范围:|x|, |y| ≤ 1e8
|
||||
{example}
|
||||
|
||||
### 答案格式
|
||||
将答案包裹在[answer]标记中:
|
||||
[answer]
|
||||
你的答案
|
||||
[/answer]"""
|
||||
return prompt
|
||||
|
||||
@staticmethod
|
||||
def extract_output(output):
|
||||
# 使用非贪婪匹配查找最后一个答案块
|
||||
matches = re.findall(r'\[answer\]\s*(.*?)\s*\[/answer\]', output, re.DOTALL)
|
||||
if not matches:
|
||||
return None
|
||||
|
||||
last_answer = matches[-1].strip()
|
||||
if last_answer == "-1":
|
||||
return "-1"
|
||||
|
||||
try:
|
||||
points = [tuple(map(int, line.strip().split())) for line in last_answer.split('\n') if line.strip()]
|
||||
return points
|
||||
except:
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
def _verify_correction(cls, solution, identity):
|
||||
n, m = identity['n'], identity['m']
|
||||
|
||||
# 处理无解情况验证
|
||||
if solution == "-1":
|
||||
return m == 3 and n > 4
|
||||
|
||||
# 检查基本格式
|
||||
if not isinstance(solution, list) or len(solution) != n:
|
||||
return False
|
||||
|
||||
# 检查坐标范围和唯一性
|
||||
seen = set()
|
||||
for x, y in solution:
|
||||
if abs(x) > 1e8 or abs(y) > 1e8:
|
||||
return False
|
||||
if (x, y) in seen:
|
||||
return False
|
||||
seen.add((x, y))
|
||||
|
||||
# 检查三点共线
|
||||
for i in range(n):
|
||||
for j in range(i+1, n):
|
||||
for k in range(j+1, n):
|
||||
a, b, c = solution[i], solution[j], solution[k]
|
||||
# 计算面积法判断共线
|
||||
area = (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0])
|
||||
if area == 0:
|
||||
return False
|
||||
|
||||
# 计算凸包
|
||||
hull = cls.convex_hull(solution)
|
||||
return len(hull) == m
|
||||
|
||||
@staticmethod
|
||||
def convex_hull(points):
|
||||
"""Andrew's monotone chain algorithm"""
|
||||
points = sorted(set(points))
|
||||
if len(points) <= 1:
|
||||
return points
|
||||
|
||||
lower = []
|
||||
for p in points:
|
||||
while len(lower) >= 2:
|
||||
a, b = lower[-2], lower[-1]
|
||||
cross = (b[0] - a[0]) * (p[1] - a[1]) - (b[1] - a[1]) * (p[0] - a[0])
|
||||
if cross > 0:
|
||||
break
|
||||
lower.pop()
|
||||
lower.append(p)
|
||||
|
||||
upper = []
|
||||
for p in reversed(points):
|
||||
while len(upper) >= 2:
|
||||
a, b = upper[-2], upper[-1]
|
||||
cross = (b[0] - a[0]) * (p[1] - a[1]) - (b[1] - a[1]) * (p[0] - a[0])
|
||||
if cross > 0:
|
||||
break
|
||||
upper.pop()
|
||||
upper.append(p)
|
||||
|
||||
return lower[:-1] + upper[:-1]
|
||||
Loading…
Add table
Add a link
Reference in a new issue