restructure, slow security solution
This commit is contained in:
42
asecbadge.py
Normal file
42
asecbadge.py
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
from collections import deque, defaultdict
|
||||||
|
from intset import IntSet
|
||||||
|
|
||||||
|
N, L, B = map(int, input().split())
|
||||||
|
|
||||||
|
S, D = map(int, input().split())
|
||||||
|
|
||||||
|
rooms = defaultdict(dict)
|
||||||
|
|
||||||
|
ALL = IntSet(1, B + 1)
|
||||||
|
NONE = IntSet()
|
||||||
|
|
||||||
|
for i in range(L):
|
||||||
|
a, b, x, y = map(int, input().split())
|
||||||
|
rooms[a][b] = IntSet(x, y + 1)
|
||||||
|
|
||||||
|
ranges = defaultdict(lambda: NONE)
|
||||||
|
ranges[S] = ALL
|
||||||
|
|
||||||
|
q = deque([S])
|
||||||
|
|
||||||
|
while q:
|
||||||
|
if len(ranges[D]) == B:
|
||||||
|
break
|
||||||
|
|
||||||
|
curr = q.pop()
|
||||||
|
|
||||||
|
# if curr == D:
|
||||||
|
# continue
|
||||||
|
|
||||||
|
for neighbor, r in rooms[curr].items():
|
||||||
|
old = ranges[neighbor]
|
||||||
|
new = ranges[neighbor] | ranges[curr] & r
|
||||||
|
if old != new:
|
||||||
|
# try:
|
||||||
|
# q.remove(neighbor)
|
||||||
|
# except ValueError:
|
||||||
|
# pass
|
||||||
|
q.append(neighbor)
|
||||||
|
ranges[neighbor] = new
|
||||||
|
|
||||||
|
print(len(ranges[D]))
|
||||||
42
asecbadge_back.py
Normal file
42
asecbadge_back.py
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
from collections import deque, defaultdict
|
||||||
|
from intset import IntSet
|
||||||
|
|
||||||
|
N, L, B = map(int, input().split())
|
||||||
|
|
||||||
|
S, D = map(int, input().split())
|
||||||
|
|
||||||
|
rooms = defaultdict(dict)
|
||||||
|
|
||||||
|
ALL = IntSet(1, B + 1)
|
||||||
|
NONE = IntSet()
|
||||||
|
|
||||||
|
for i in range(L):
|
||||||
|
a, b, x, y = map(int, input().split())
|
||||||
|
rooms[b][a] = IntSet(x, y + 1)
|
||||||
|
|
||||||
|
ranges = defaultdict(lambda: NONE)
|
||||||
|
ranges[D] = ALL
|
||||||
|
|
||||||
|
q = [D]
|
||||||
|
|
||||||
|
while q:
|
||||||
|
# if len(ranges[D]) == B:
|
||||||
|
# break
|
||||||
|
|
||||||
|
curr = q.pop(0)
|
||||||
|
|
||||||
|
# if curr == D:
|
||||||
|
# continue
|
||||||
|
|
||||||
|
for neighbor, r in rooms[curr].items():
|
||||||
|
old = ranges[neighbor]
|
||||||
|
new = ranges[neighbor] | (ranges[curr] & r)
|
||||||
|
if len(old) != len(new):
|
||||||
|
# try:
|
||||||
|
# q.remove(neighbor)
|
||||||
|
# except ValueError:
|
||||||
|
# pass
|
||||||
|
q.append(neighbor)
|
||||||
|
ranges[neighbor] = new
|
||||||
|
|
||||||
|
print(len(ranges[S]))
|
||||||
50
asecbadge_iter.py
Normal file
50
asecbadge_iter.py
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
from collections import deque, defaultdict
|
||||||
|
|
||||||
|
N, L, B = map(int, input().split())
|
||||||
|
|
||||||
|
S, D = map(int, input().split())
|
||||||
|
|
||||||
|
rooms = defaultdict(dict)
|
||||||
|
|
||||||
|
bounds = set()
|
||||||
|
|
||||||
|
for _ in range(L):
|
||||||
|
a, b, x, y = map(int, input().split())
|
||||||
|
rooms[a][b] = x, y + 1
|
||||||
|
bounds.add(x)
|
||||||
|
bounds.add(y + 1)
|
||||||
|
|
||||||
|
total = 0
|
||||||
|
|
||||||
|
bounds = sorted(bounds)
|
||||||
|
|
||||||
|
|
||||||
|
def piecewise(seq):
|
||||||
|
it = iter(seq)
|
||||||
|
last = next(it)
|
||||||
|
for new in it:
|
||||||
|
yield last, new
|
||||||
|
last = new
|
||||||
|
|
||||||
|
|
||||||
|
for a, b in piecewise(bounds):
|
||||||
|
q = deque([S])
|
||||||
|
visited = [0] * L
|
||||||
|
|
||||||
|
while q:
|
||||||
|
curr = q.pop()
|
||||||
|
visited[curr - 1] = 1
|
||||||
|
nbors = rooms[curr].items()
|
||||||
|
|
||||||
|
if curr == D:
|
||||||
|
total += b - a
|
||||||
|
break
|
||||||
|
|
||||||
|
for n, (la, lb) in nbors:
|
||||||
|
if visited[n - 1]:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if a >= la and b <= lb:
|
||||||
|
q.append(n)
|
||||||
|
|
||||||
|
print(total)
|
||||||
111
intset.py
Normal file
111
intset.py
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
class IntSet:
|
||||||
|
def __init__(self, *bounds):
|
||||||
|
"""Bounds must be tuples of the form (a, b),
|
||||||
|
where integers a <= x < b are included in the set.
|
||||||
|
"""
|
||||||
|
|
||||||
|
if not bounds:
|
||||||
|
bounds = [0, 0]
|
||||||
|
|
||||||
|
self.bounds = list(bounds)
|
||||||
|
|
||||||
|
def simplify(self):
|
||||||
|
i = 0
|
||||||
|
while i < len(self.bounds) - 1:
|
||||||
|
if i % 2 == 0:
|
||||||
|
if self.bounds[i] >= self.bounds[i + 1]:
|
||||||
|
del self.bounds[i:i + 2]
|
||||||
|
else:
|
||||||
|
i += 1
|
||||||
|
else:
|
||||||
|
if self.bounds[i] >= self.bounds[i + 1]:
|
||||||
|
if self.bounds[i] >= self.bounds[i + 2]:
|
||||||
|
del self.bounds[i + 1:i + 3]
|
||||||
|
else:
|
||||||
|
del self.bounds[i:i + 2]
|
||||||
|
else:
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
def __or__(self, other):
|
||||||
|
bounds = None
|
||||||
|
j = k = 0
|
||||||
|
|
||||||
|
while j < len(self.bounds) - 1 or k < len(other.bounds) - 1:
|
||||||
|
if k >= len(other.bounds) - 1:
|
||||||
|
a, b = self.bounds[j:j + 2]
|
||||||
|
j += 2
|
||||||
|
elif j >= len(self.bounds) - 1:
|
||||||
|
a, b = other.bounds[k:k + 2]
|
||||||
|
k += 2
|
||||||
|
elif self.bounds[j] < other.bounds[k]:
|
||||||
|
a, b = self.bounds[j:j + 2]
|
||||||
|
j += 2
|
||||||
|
else:
|
||||||
|
a, b = other.bounds[k:k + 2]
|
||||||
|
k += 2
|
||||||
|
|
||||||
|
if a >= b:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if not bounds:
|
||||||
|
bounds = [a, b]
|
||||||
|
continue
|
||||||
|
|
||||||
|
e = bounds[-1]
|
||||||
|
|
||||||
|
if e >= a:
|
||||||
|
if e >= b:
|
||||||
|
continue
|
||||||
|
bounds[-1] = b
|
||||||
|
else:
|
||||||
|
bounds.append(a)
|
||||||
|
bounds.append(b)
|
||||||
|
|
||||||
|
if not bounds:
|
||||||
|
bounds = [0, 0]
|
||||||
|
|
||||||
|
new = IntSet()
|
||||||
|
new.bounds = bounds
|
||||||
|
return new
|
||||||
|
|
||||||
|
def __and__(self, other):
|
||||||
|
bounds = []
|
||||||
|
|
||||||
|
i = j = 0
|
||||||
|
while i < len(self.bounds) - 1 and j < len(other.bounds) - 1:
|
||||||
|
a, b = self.bounds[i:i + 2]
|
||||||
|
c, d = other.bounds[j:j + 2]
|
||||||
|
if b > c and a < d:
|
||||||
|
bounds.append(max(a, c))
|
||||||
|
bounds.append(min(b, d))
|
||||||
|
if b < d:
|
||||||
|
i += 2 # toss a b
|
||||||
|
else:
|
||||||
|
j += 2 # toss c d
|
||||||
|
|
||||||
|
new = IntSet()
|
||||||
|
new.bounds = bounds
|
||||||
|
new.simplify()
|
||||||
|
return new
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
return self.bounds == other.bounds
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
for a, b in self.pairs:
|
||||||
|
yield from range(a, b)
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
return sum(b - a if b > a else 0 for a, b in self.pairs)
|
||||||
|
|
||||||
|
def __lt__(self, other):
|
||||||
|
return len(self) < len(other)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def pairs(self):
|
||||||
|
it = iter(self.bounds)
|
||||||
|
while True:
|
||||||
|
yield next(it), next(it)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return 'U'.join('[{0},{1})'.format(a, b) for a, b in self.pairs)
|
||||||
4
make_and_test.py
Normal file
4
make_and_test.py
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
import subprocess
|
||||||
|
|
||||||
|
subprocess.call(['python', 'make_nonsense.py'])
|
||||||
|
subprocess.call(['python', 'icpc_test.py', 'asecbadge_multi.py', 'security', '5'])
|
||||||
22
make_nonsense.py
Normal file
22
make_nonsense.py
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
from itertools import islice, permutations
|
||||||
|
from random import randint, sample
|
||||||
|
|
||||||
|
N, L, B = 1000, 5000, 100_000_000
|
||||||
|
S = D = 0
|
||||||
|
while S == D:
|
||||||
|
S, D = randint(1, N), randint(1, N)
|
||||||
|
|
||||||
|
pairs = sample(list(permutations(range(N), r=2)), L)
|
||||||
|
rows = []
|
||||||
|
|
||||||
|
for a, b in pairs:
|
||||||
|
x = randint(1, B)
|
||||||
|
y = randint(x, B)
|
||||||
|
|
||||||
|
rows.append((a, b, x, y))
|
||||||
|
|
||||||
|
with open('test/security/nonsense.in', 'w') as f:
|
||||||
|
f.writelines(' '.join(map(str, tup)) + '\n' for tup in [(N, L, B), (S, D)] + rows)
|
||||||
|
|
||||||
|
with open('test/security/nonsense.ans', 'w') as f:
|
||||||
|
f.write('27\n')
|
||||||
57
secbadge.py
57
secbadge.py
@@ -1,57 +0,0 @@
|
|||||||
##N, L, B = input().strip().split()
|
|
||||||
##S, D = input().strip().split()
|
|
||||||
|
|
||||||
class Range():
|
|
||||||
|
|
||||||
def __init__(self, ranges):
|
|
||||||
self.ranges = ranges
|
|
||||||
|
|
||||||
def __add__(self, other):
|
|
||||||
new_ranges = list(self.ranges)
|
|
||||||
for rang1 in other.ranges:
|
|
||||||
for i, rang2 in enumerate(new_ranges):
|
|
||||||
if rang1[0] <= rang2[0] and rang1[1] >= rang2[1]:
|
|
||||||
new_ranges[i] = rang1
|
|
||||||
break
|
|
||||||
if rang1[0] >= rang2[0] and rang1[1] <= rang2[1]:
|
|
||||||
break
|
|
||||||
if rang1[1] >= rang2[0]-1 and rang1[1] <= rang2[1]:
|
|
||||||
new_ranges[i] = (rang1[0], rang2[1])
|
|
||||||
break
|
|
||||||
if rang1[0] >= rang2[0] and rang1[0] <= rang2[1]+1:
|
|
||||||
new_ranges[i] = (rang2[0], rang1[1])
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
new_ranges.append(rang1)
|
|
||||||
return Range(new_ranges)
|
|
||||||
|
|
||||||
def __mul__(self, other):
|
|
||||||
new_ranges = []
|
|
||||||
for rang1 in other.ranges:
|
|
||||||
cand = rang1
|
|
||||||
for rang2 in self.ranges:
|
|
||||||
if rang1[0] <= rang2[0] and rang1[1] >= rang2[1]:
|
|
||||||
cand = rand2
|
|
||||||
elif rang1[0] >= rang2[0] and rang1[1] <= rang2[1]:
|
|
||||||
pass
|
|
||||||
elif rang1[1] >= rang2[0] and rang1[1] <= rang2[1]:
|
|
||||||
cand (rang2[0], rang1[1])
|
|
||||||
elif rang1[0] >= rang2[0] and rang1[0] <= rang2[1]:
|
|
||||||
cand = (rang1[0], rang2[1])
|
|
||||||
else:
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
new_ranges.append(cand)
|
|
||||||
return Range(new_ranges)
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return str(*self.ranges)
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return str(self.ranges)
|
|
||||||
|
|
||||||
Range.INF = Range([(-float('inf'), float('inf'))])
|
|
||||||
|
|
||||||
a = Range.INF
|
|
||||||
b = Range([(3, 4)])
|
|
||||||
print(a+b)
|
|
||||||
1
test/security/custom_1.ans
Normal file
1
test/security/custom_1.ans
Normal file
@@ -0,0 +1 @@
|
|||||||
|
10
|
||||||
6
test/security/custom_1.in
Normal file
6
test/security/custom_1.in
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
3 4 10
|
||||||
|
1 3
|
||||||
|
1 3 1 5
|
||||||
|
1 2 6 10
|
||||||
|
2 3 6 10
|
||||||
|
3 2 6 10
|
||||||
1
test/security/custom_2.ans
Normal file
1
test/security/custom_2.ans
Normal file
@@ -0,0 +1 @@
|
|||||||
|
0
|
||||||
5
test/security/custom_2.in
Normal file
5
test/security/custom_2.in
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
4 3 10
|
||||||
|
1 4
|
||||||
|
1 3 1 5
|
||||||
|
1 2 6 10
|
||||||
|
2 3 6 10
|
||||||
Reference in New Issue
Block a user