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
284
internbootcamp/bootcamp/dcompletetripartite/dcompletetripartite.py
Executable file
284
internbootcamp/bootcamp/dcompletetripartite/dcompletetripartite.py
Executable file
|
|
@ -0,0 +1,284 @@
|
|||
"""#
|
||||
|
||||
### 谜题描述
|
||||
You have a simple undirected graph consisting of n vertices and m edges. The graph doesn't contain self-loops, there is at most one edge between a pair of vertices. The given graph can be disconnected.
|
||||
|
||||
Let's make a definition.
|
||||
|
||||
Let v_1 and v_2 be two some nonempty subsets of vertices that do not intersect. Let f(v_{1}, v_{2}) be true if and only if all the conditions are satisfied:
|
||||
|
||||
1. There are no edges with both endpoints in vertex set v_1.
|
||||
2. There are no edges with both endpoints in vertex set v_2.
|
||||
3. For every two vertices x and y such that x is in v_1 and y is in v_2, there is an edge between x and y.
|
||||
|
||||
|
||||
|
||||
Create three vertex sets (v_{1}, v_{2}, v_{3}) which satisfy the conditions below;
|
||||
|
||||
1. All vertex sets should not be empty.
|
||||
2. Each vertex should be assigned to only one vertex set.
|
||||
3. f(v_{1}, v_{2}), f(v_{2}, v_{3}), f(v_{3}, v_{1}) are all true.
|
||||
|
||||
|
||||
|
||||
Is it possible to create such three vertex sets? If it's possible, print matching vertex set for each vertex.
|
||||
|
||||
Input
|
||||
|
||||
The first line contains two integers n and m (3 ≤ n ≤ 10^{5}, 0 ≤ m ≤ min(3 ⋅ 10^{5}, (n(n-1))/(2))) — the number of vertices and edges in the graph.
|
||||
|
||||
The i-th of the next m lines contains two integers a_{i} and b_{i} (1 ≤ a_{i} < b_{i} ≤ n) — it means there is an edge between a_{i} and b_{i}. The graph doesn't contain self-loops, there is at most one edge between a pair of vertices. The given graph can be disconnected.
|
||||
|
||||
Output
|
||||
|
||||
If the answer exists, print n integers. i-th integer means the vertex set number (from 1 to 3) of i-th vertex. Otherwise, print -1.
|
||||
|
||||
If there are multiple answers, print any.
|
||||
|
||||
Examples
|
||||
|
||||
Input
|
||||
|
||||
|
||||
6 11
|
||||
1 2
|
||||
1 3
|
||||
1 4
|
||||
1 5
|
||||
1 6
|
||||
2 4
|
||||
2 5
|
||||
2 6
|
||||
3 4
|
||||
3 5
|
||||
3 6
|
||||
|
||||
|
||||
Output
|
||||
|
||||
|
||||
1 2 2 3 3 3
|
||||
|
||||
Input
|
||||
|
||||
|
||||
4 6
|
||||
1 2
|
||||
1 3
|
||||
1 4
|
||||
2 3
|
||||
2 4
|
||||
3 4
|
||||
|
||||
|
||||
Output
|
||||
|
||||
|
||||
-1
|
||||
|
||||
Note
|
||||
|
||||
In the first example, if v_{1} = \{ 1 \}, v_{2} = \{ 2, 3 \}, and v_{3} = \{ 4, 5, 6 \} then vertex sets will satisfy all conditions. But you can assign vertices to vertex sets in a different way; Other answers like \"2 3 3 1 1 1\" will be accepted as well.
|
||||
|
||||
<image>
|
||||
|
||||
In the second example, it's impossible to make such vertex sets.
|
||||
|
||||
Here is a reference code to solve this task. You can use this to help you genereate cases or validate the solution.
|
||||
```python
|
||||
import os
|
||||
import sys
|
||||
from atexit import register
|
||||
from io import BytesIO
|
||||
sys.stdin = BytesIO(os.read(0, os.fstat(0).st_size))
|
||||
sys.stdout = BytesIO()
|
||||
register(lambda: os.write(1, sys.stdout.getvalue()))
|
||||
input = lambda: sys.stdin.readline().rstrip('\r\n')
|
||||
n,m = map(int,input().split(\" \"))
|
||||
connected = [[]for i in range(n+1)]
|
||||
edges = []
|
||||
for i in range(m):
|
||||
a,b = map(int,input().split(\" \"))
|
||||
connected[a].append(b)
|
||||
connected[b].append(a)
|
||||
edges.append((a,b))
|
||||
flag = True
|
||||
labels = [0]*(n+1)
|
||||
labels[1] = 1
|
||||
alln = set(range(1,n+1))
|
||||
if len(connected[1]) >0:
|
||||
node2 = connected[1][0]
|
||||
else:
|
||||
flag = False
|
||||
if flag:
|
||||
s1 = alln-set(connected[1])
|
||||
s2 = alln-set(connected[node2])
|
||||
s3 = alln-s1-s2
|
||||
n1,n2,n3 = len(s1),len(s2),len(s3)
|
||||
if n1+n2+n3!=n or min(n1,n2,n3) == 0:
|
||||
flag = False
|
||||
for i in list(s1):
|
||||
labels[i] = 1
|
||||
for i in list(s2):
|
||||
labels[i] = 2
|
||||
for i in list(s3):
|
||||
labels[i] = 3
|
||||
cnts = [0]*3
|
||||
for a,b in edges:
|
||||
if labels[a] == labels[b]:
|
||||
flag = False
|
||||
break
|
||||
cnts[labels[a]-1] += 1
|
||||
cnts[labels[b]-1] += 1
|
||||
if flag and cnts[0] == n1*(n2+n3) and cnts[1] == n2*(n1+n3) and cnts[2] == n3*(n1+n2):
|
||||
out = []
|
||||
for i in range(1,n+1):
|
||||
out.append(str(labels[i]))
|
||||
print \" \".join(out)
|
||||
else:
|
||||
print -1
|
||||
else:
|
||||
print -1
|
||||
```
|
||||
|
||||
|
||||
请完成上述谜题的训练场环境类实现,包括所有必要的方法。
|
||||
"""
|
||||
|
||||
from bootcamp import Basebootcamp
|
||||
from bootcamp import Basebootcamp
|
||||
import re
|
||||
import random
|
||||
|
||||
class Dcompletetripartitebootcamp(Basebootcamp):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
def case_generator(self):
|
||||
# 生成符合题目要求的n范围 (3 ≤ n ≤ 1e5)
|
||||
n = random.randint(3, 20) # 示例使用较小范围便于测试,实际可调至1e5
|
||||
|
||||
# 确保三个子集都至少有一个顶点
|
||||
sizes = [1, 1, 1]
|
||||
remaining = n - 3
|
||||
for _ in range(remaining):
|
||||
sizes[random.randint(0, 2)] += 1
|
||||
|
||||
# 随机分配顶点到三个子集
|
||||
vertices = list(range(1, n+1))
|
||||
random.shuffle(vertices)
|
||||
|
||||
v1 = sorted(vertices[:sizes[0]])
|
||||
v2 = sorted(vertices[sizes[0]:sizes[0]+sizes[1]])
|
||||
v3 = sorted(vertices[sizes[0]+sizes[1]:])
|
||||
|
||||
# 计算跨子集边的总数(数学公式直接计算)
|
||||
m = sizes[0]*sizes[1] + sizes[1]*sizes[2] + sizes[2]*sizes[0]
|
||||
|
||||
# 生成边集合(仅记录跨子集的边)
|
||||
edges = []
|
||||
# V1-V2边
|
||||
for a in v1:
|
||||
edges.extend((min(a,b), max(a,b)) for b in v2)
|
||||
# V2-V3边
|
||||
for b in v2:
|
||||
edges.extend((min(b,c), max(b,c)) for c in v3)
|
||||
# V3-V1边
|
||||
for c in v3:
|
||||
edges.extend((min(c,a), max(c,a)) for a in v1)
|
||||
|
||||
# 去重并排序
|
||||
edges = sorted(list(set(edges)))
|
||||
|
||||
return {
|
||||
"n": n,
|
||||
"m": len(edges),
|
||||
"edges": edges,
|
||||
"expected_sets": {
|
||||
1: v1,
|
||||
2: v2,
|
||||
3: v3
|
||||
}
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def prompt_func(question_case) -> str:
|
||||
input_lines = [f"{question_case['n']} {question_case['m']}"]
|
||||
input_lines.extend(f"{a} {b}" for a, b in question_case['edges'])
|
||||
input_block = "\n".join(input_lines)
|
||||
|
||||
prompt = f"""Given an undirected graph with {question_case['n']} vertices and {question_case['m']} edges, determine if the vertices can be partitioned into three non-empty subsets meeting these conditions:
|
||||
|
||||
1. All vertices are in exactly one subset
|
||||
2. For each subset pair (V1,V2), (V2,V3), (V3,V1):
|
||||
- No internal edges within either subset
|
||||
- Complete bipartite connections between subsets
|
||||
|
||||
Input:
|
||||
{input_block}
|
||||
|
||||
Output format:
|
||||
If possible: {question_case['n']} space-separated integers (1/2/3)
|
||||
If impossible: -1
|
||||
|
||||
Place your final answer between [answer] and [/answer]. Example:
|
||||
[answer]1 2 2 3 3 3[/answer]"""
|
||||
|
||||
return prompt
|
||||
|
||||
@staticmethod
|
||||
def extract_output(output):
|
||||
matches = re.findall(r'\[answer\](.*?)\[\/answer\]', output, re.DOTALL)
|
||||
return matches[-1].strip() if matches else None
|
||||
|
||||
@classmethod
|
||||
def _verify_correction(cls, solution, identity):
|
||||
# 快速拒绝错误格式
|
||||
if not solution or solution.strip() == "-1":
|
||||
return False
|
||||
|
||||
try:
|
||||
labels = list(map(int, solution.split()))
|
||||
except ValueError:
|
||||
return False
|
||||
|
||||
# 验证基础条件
|
||||
if len(labels) != identity['n']:
|
||||
return False
|
||||
if not all(l in {1,2,3} for l in labels):
|
||||
return False
|
||||
|
||||
# 构建分组映射
|
||||
groups = {1: set(), 2: set(), 3: set()}
|
||||
for v, l in enumerate(labels, 1):
|
||||
groups[l].add(v)
|
||||
|
||||
# 检查非空子集
|
||||
if any(len(groups[i]) == 0 for i in [1,2,3]):
|
||||
return False
|
||||
|
||||
# 验证边约束
|
||||
edge_set = set(map(tuple, identity['edges']))
|
||||
|
||||
# 验证每个子集的内部无连接
|
||||
for group in groups.values():
|
||||
for a in group:
|
||||
for b in group:
|
||||
if a < b and (a, b) in edge_set:
|
||||
return False
|
||||
|
||||
# 验证跨子集的完全连接
|
||||
expected_pairs = [
|
||||
(groups[1], groups[2]),
|
||||
(groups[2], groups[3]),
|
||||
(groups[3], groups[1])
|
||||
]
|
||||
for s1, s2 in expected_pairs:
|
||||
for a in s1:
|
||||
for b in s2:
|
||||
if a > b:
|
||||
a, b = b, a
|
||||
if (a, b) not in edge_set:
|
||||
return False
|
||||
|
||||
return True
|
||||
Loading…
Add table
Add a link
Reference in a new issue