init-commit

This commit is contained in:
lilinyang 2025-05-23 15:27:15 +08:00
commit 18a552597a
3461 changed files with 1150579 additions and 0 deletions

View file

@ -0,0 +1,388 @@
"""#
### 谜题描述
To improve the boomerang throwing skills of the animals, Zookeeper has set up an n × n grid with some targets, where each row and each column has at most 2 targets each. The rows are numbered from 1 to n from top to bottom, and the columns are numbered from 1 to n from left to right.
For each column, Zookeeper will throw a boomerang from the bottom of the column (below the grid) upwards. When the boomerang hits any target, it will bounce off, make a 90 degree turn to the right and fly off in a straight line in its new direction. The boomerang can hit multiple targets and does not stop until it leaves the grid.
<image>
In the above example, n=6 and the black crosses are the targets. The boomerang in column 1 (blue arrows) bounces 2 times while the boomerang in column 3 (red arrows) bounces 3 times.
The boomerang in column i hits exactly a_i targets before flying out of the grid. It is known that a_i 3.
However, Zookeeper has lost the original positions of the targets. Thus, he asks you to construct a valid configuration of targets that matches the number of hits for each column, or tell him that no such configuration exists. If multiple valid configurations exist, you may print any of them.
Input
The first line contains a single integer n (1 n 10^5).
The next line contains n integers a_1,a_2,,a_n (0 a_i 3).
Output
If no configuration of targets exist, print -1.
Otherwise, on the first line print a single integer t (0 t 2n): the number of targets in your configuration.
Then print t lines with two spaced integers each per line. Each line should contain two integers r and c (1 r,c n), where r is the target's row and c is the target's column. All targets should be different.
Every row and every column in your configuration should have at most two targets each.
Examples
Input
6
2 0 3 0 1 1
Output
5
2 1
2 5
3 3
3 6
5 6
Input
1
0
Output
0
Input
6
3 2 2 2 1 1
Output
-1
Note
For the first test, the answer configuration is the same as in the picture from the statement.
For the second test, the boomerang is not supposed to hit anything, so we can place 0 targets.
For the third test, the following configuration of targets matches the number of hits, but is not allowed as row 3 has 4 targets.
<image>
It can be shown for this test case that no valid configuration of targets will result in the given number of target hits.
Here is a reference code to solve this task. You can use this to help you genereate cases or validate the solution.
```python
import atexit, io, sys
# A stream implementation using an in-memory bytes
# buffer. It inherits BufferedIOBase.
buffer = io.BytesIO()
sys.stdout = buffer
# print via here
@atexit.register
def write():
sys.__stdout__.write(buffer.getvalue())
for _ in range(1):
n=input()
a=map(int,raw_input().split())
ok=1
v=[]
v2=[]
ans=[]
for i in range(n-1,-1,-1):
if a[i]:
if a[i]==1:
ans.append([i+1,i+1])
v.append(i)
if a[i]==2:
if len(v)==0:
ok=0;break
else:
p=v.pop()
ans.append([p+1,i+1])
v2.append(i)
if a[i]==3:
if (len(v)+len(v2))==0:
ok=0;break
elif len(v2):
p=v2.pop()
ans.append([i+1,i+1])
ans.append([i+1,p+1])
v2.append(i)
else:
p=v.pop()
ans.append([i+1,i+1])
ans.append([i+1,p+1])
v2.append(i)
if ok:
print len(ans)
for i in ans:
print i[0],i[1]
else:
print -1
```
请完成上述谜题的训练场环境类实现包括所有必要的方法
"""
from bootcamp import Basebootcamp
import re
import random
from collections import defaultdict
from bootcamp import Basebootcamp
class Dbouncingboomerangsbootcamp(Basebootcamp):
def __init__(self, **params):
self.n = params.get('n', 6)
self.force_solvable = params.get('force_solvable', None) # 用于控制生成有解/无解案例
def case_generator(self):
# 生成有效靶子配置或不可解案例
if self.force_solvable is False:
return self.generate_unsolvable_case()
n = random.randint(1, 10)
targets, a = self.generate_valid_case(n)
if targets is not None:
return {'n': n, 'a': a, 'solvable': True, 'solution': targets}
# 生成不可解案例(当无法生成有效解时)
a = self.generate_unsolvable_a(n)
return {'n': n, 'a': a, 'solvable': False}
def generate_valid_case(self, n):
# 生成有效靶子配置并计算对应的a值
for _ in range(100): # 尝试次数限制
targets = []
rows = defaultdict(int)
cols = defaultdict(int)
# 生成随机靶子
for _ in range(random.randint(0, 2*n)):
r = random.randint(1, n)
c = random.randint(1, n)
if (r, c) in targets:
continue
if rows[r] < 2 and cols[c] < 2:
targets.append((r, c))
rows[r] += 1
cols[c] += 1
# 计算a数组
a = self.compute_a_values(n, targets)
if all(ai <= 3 for ai in a):
# 验证参考解法
solvable, solution = self.solve_boomerang(n, a)
if solvable:
# 二次验证解法有效性
valid = True
v_rows = defaultdict(int)
v_cols = defaultdict(int)
for r, c in solution:
v_rows[r] += 1
v_cols[c] += 1
if v_rows[r] > 2 or v_cols[c] > 2:
valid = False
break
if valid:
return solution, a
return None, None
def generate_unsolvable_a(self, n):
# 生成明显矛盾的a数组如奇数个3
a = [3] * n
a[-1] = 1 # 制造无法满足的结尾
return a
@staticmethod
def solve_boomerang(n, a):
ok = True
v = []
v2 = []
ans = []
for i in range(n-1, -1, -1):
ai = a[i]
if ai == 0:
continue
elif ai == 1:
ans.append((i+1, i+1))
v.append(i)
elif ai == 2:
if not v:
ok = False
break
p = v.pop()
ans.append((p+1, i+1))
v2.append(i)
elif ai == 3:
if not v and not v2:
ok = False
break
if v2:
p = v2.pop()
ans.append((i+1, i+1))
ans.append((i+1, p+1))
v2.append(i)
else:
p = v.pop()
ans.append((i+1, i+1))
ans.append((i+1, p+1))
v2.append(i)
return (True, ans) if ok else (False, None)
@staticmethod
def compute_a_values(n, solution):
target_set = set(solution)
computed_a = [0] * n
for c in range(n):
current_col = c + 1
hits = 0
direction = 'up'
current_r, current_c = n, current_col
visited = set()
while True:
if direction == 'up':
found = None
for r in range(current_r, 0, -1):
if (r, current_c) in target_set and (r, current_c) not in visited:
found = (r, current_c)
break
if not found:
break
visited.add(found)
hits += 1
direction = 'right'
current_r, current_c = found
elif direction == 'right':
found = None
for col in range(current_c + 1, n + 1):
if (current_r, col) in target_set and (current_r, col) not in visited:
found = (current_r, col)
break
if not found:
break
visited.add(found)
hits += 1
direction = 'down'
current_r, current_c = found
elif direction == 'down':
found = None
for r in range(current_r + 1, n + 1):
if (r, current_c) in target_set and (r, current_c) not in visited:
found = (r, current_c)
break
if not found:
break
visited.add(found)
hits += 1
direction = 'left'
current_r, current_c = found
elif direction == 'left':
found = None
for col in range(current_c - 1, 0, -1):
if (current_r, col) in target_set and (current_r, col) not in visited:
found = (current_r, col)
break
if not found:
break
visited.add(found)
hits += 1
direction = 'up'
current_r, current_c = found
else:
break
computed_a[c] = hits
return computed_a
@staticmethod
def prompt_func(question_case):
n = question_case['n']
a = question_case['a']
prompt = f"""As a zookeeper, you need to arrange targets in an {n}x{n} grid where each row/column contains at most 2 targets. Dbouncingboomerangss are thrown upwards from each column's bottom. When hitting a target, they turn right 90 degrees.
Given hit counts for each column: {a}
Construct a valid configuration or output -1 if impossible. Format your answer as:
[answer]
-1
[/answer]
or list target coordinates (one per line) within [answer] tags."""
return prompt
@staticmethod
def extract_output(output):
matches = re.findall(r'\[answer\](.*?)\[/answer\]', output, re.DOTALL)
if not matches:
return None
content = matches[-1].strip()
if content == '-1':
return -1
targets = []
for line in content.split('\n'):
line = line.strip()
if not line:
continue
parts = line.split()
if len(parts) != 2:
continue
try:
r = int(parts[0])
c = int(parts[1])
if r > 0 and c > 0:
targets.append((r, c))
except:
continue
return targets if targets else None
@classmethod
def _verify_correction(cls, solution, identity):
if solution == -1:
return not identity['solvable']
if not isinstance(solution, list):
return False
n = identity['n']
a = identity['a']
seen = set()
rows = defaultdict(int)
cols = defaultdict(int)
# 验证靶子坐标有效性
for r, c in solution:
if not (1 <= r <= n) or not (1 <= c <= n):
return False
if (r, c) in seen:
return False
seen.add((r, c))
rows[r] += 1
cols[c] += 1
if rows[r] > 2 or cols[c] > 2:
return False
# 计算并验证a值
computed_a = cls.compute_a_values(n, solution)
return computed_a == a and identity['solvable']