結果
| 問題 |
No.1955 Not Prime
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2022-05-20 23:55:03 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 365 ms / 2,000 ms |
| コード長 | 4,753 bytes |
| コンパイル時間 | 183 ms |
| コンパイル使用メモリ | 82,048 KB |
| 実行使用メモリ | 101,808 KB |
| 最終ジャッジ日時 | 2024-09-20 10:20:49 |
| 合計ジャッジ時間 | 4,979 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 26 |
ソースコード
def scc(N, G):
order = []
used = [False]*N
group = [None]*N
RG = [[] for _ in range(N)]
for i in range(N):
for j in G[i]:
RG[j].append(i)
def dfs(pos):
stack = [(1, pos), (0, pos)]
while stack:
t, pos = stack.pop()
if t == 0:
if used[pos]:
stack.pop()
continue
used[pos] = True
for npos in G[pos]:
if not used[npos]:
stack.append((1, npos))
stack.append((0, npos))
else:
order.append(pos)
def rdfs(pos, col):
stack = [pos]
group[pos] = col
used[pos] = True
while stack:
pos = stack.pop()
for npos in RG[pos]:
if not used[npos]:
used[npos] = True
group[npos] = col
stack.append(npos)
for i in range(N):
if not used[i]:
dfs(i)
used = [False]*N
label = 0
for s in reversed(order):
if not used[s]:
rdfs(s, label)
label += 1
return label, group
class Two_SAT:
def __init__(self, n):
self.n = n
self.G = [[] for _ in range(2 * n)]
# a V B
# neg_i = False -> a = i
# neg_i = True -> a = ¬i
def add_edge(self, i, j, neg_i, neg_j):
i0 = i
i1 = i + self.n
if neg_i:
i0, i1 = i1, i0
j0 = j
j1 = j + self.n
if neg_j:
j0, j1 = j1, j0
self.G[i1].append(j0)
self.G[j1].append(i0)
def const(self):
_, self.group = scc(2 * self.n, self.G)
def check(self):
for i in range(self.n):
if self.group[i] == self.group[i + self.n]:
return False
return True
def assign(self):
ret = [False] * self.n
for i in range(self.n):
if self.group[i] > self.group[i + self.n]:
ret[i] = True
return ret
N = 1000100
isprime = [True] * N
isprime[0] = isprime[1] = False
for i in range(2, int(N ** 0.5 + 1)):
if not isprime[i]:
continue
for j in range(i * i, N, i):
isprime[j] = False
n = int(input())
ab = [input().split() for _ in range(n)]
sat = Two_SAT(n)
for i in range(n):
ai, bi = ab[i]
c1 = int(ai + bi)
c2 = int(bi + ai)
if not isprime[c1] and not isprime[c2]:
pass
elif not isprime[c1]:
sat.add_edge(i, i, False, False)
elif not isprime[c2]:
sat.add_edge(i, i, True, True)
else:
print("No")
exit()
for j in range(i + 1, n):
aj, bj = ab[j]
f1 = (not isprime[int(ai + bj)]) and (not isprime[int(aj + bi)])
f2 = (not isprime[int(bi + bj)]) and (not isprime[int(aj + ai)])
f3 = (not isprime[int(ai + aj)]) and (not isprime[int(bj + bi)])
f4 = (not isprime[int(bi + aj)]) and (not isprime[int(bj + ai)])
cnt = f1 + f2 + f3 + f4
if cnt == 0:
print("No")
exit()
elif cnt == 4:
continue
elif cnt == 3:
if f1 and f3:
t1 = False
else:
t1 = True
if f1 and f2:
t2 = False
else:
t2 = True
sat.add_edge(i, j, t1, t2)
elif cnt == 2:
if f1 and f3:
sat.add_edge(i, j, False, True)
sat.add_edge(i, j, False, False)
elif f2 and f4:
sat.add_edge(i, j, True, True)
sat.add_edge(i, j, True, False)
elif f1 and f2:
sat.add_edge(i, j, False, False)
sat.add_edge(i, j, True, False)
elif f3 and f4:
sat.add_edge(i, j, False, True)
sat.add_edge(i, j, True, True)
elif f1 and f4:
sat.add_edge(i, j, False, True)
sat.add_edge(i, j, True, False)
else:
sat.add_edge(i, j, False, False)
sat.add_edge(i, j, True, True)
else:
if f1:
t1 = False
t2 = False
elif f2:
t1 = True
t2 = False
elif f3:
t1 = False
t2 = True
else:
t1 = True
t2 = True
sat.add_edge(i, j, t1, t2)
sat.add_edge(i, j, t1 ^ True, t2)
sat.add_edge(i, j, t1, t2 ^ True)
sat.const()
if sat.check():
print("Yes")
else:
print("No")