結果
| 問題 | No.1427 Simplified Tetris |
| コンテスト | |
| ユーザー |
titia
|
| 提出日時 | 2026-01-07 06:01:54 |
| 言語 | PyPy3 (7.3.17) |
| 結果 |
AC
|
| 実行時間 | 1,941 ms / 2,000 ms |
| コード長 | 4,786 bytes |
| 記録 | |
| コンパイル時間 | 376 ms |
| コンパイル使用メモリ | 82,420 KB |
| 実行使用メモリ | 79,520 KB |
| 最終ジャッジ日時 | 2026-01-07 06:02:06 |
| 合計ジャッジ時間 | 11,709 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 4 |
| other | AC * 37 |
ソースコード
import sys
input = sys.stdin.readline
from collections import defaultdict,deque
from time import time
time0=time()
H,W=map(int,input().split())
MAP0=[input().strip() for i in range(H)]
ALPHA="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
flag=0
LIST=[]
for i in range(H):
if MAP0[i].count("#")==W:
print("No")
exit()
if MAP0[i].count("#")>0:
LIST.append(i)
if flag==0:
if MAP0[i].count("#")>0:
flag=1
else:
if MAP0[i].count("#")==0:
print("No")
exit()
if flag==0:
print("Yes")
for m in MAP0:
print(m)
exit()
def calc(MAP):
N=len(MAP)
M=len(MAP[0])
start=N*M
goal=N*M+1
# dinic法
V=N*M+2
EDGE=[defaultdict(int) for i in range(V)]
for i in range(N):
for j in range(M):
if (i+j)%2==0 and MAP[i][j]=="#":
u,v,c=start,i*M+j,1
EDGE[u][v]=c
for x,y in [(i+1,j),(i-1,j),(i,j+1),(i,j-1)]:
if 0<=x<N and 0<=y<M and MAP[x][y]=="#":
u,v,c=i*M+j,x*M+y,1
EDGE[u][v]=c
if (i+j)%2==1 and MAP[i][j]=="#":
u,v,c=i*M+j,goal,1
EDGE[u][v]=c
ANS=0
while True:
# まずBFSする
DIS=[-1]*V
Q=deque([start])
DIS[start]=0
EDGE2=[[] for i in range(V)]
while Q:
x=Q.popleft()
for to in EDGE[x]:
if EDGE[x][to]==0:
continue
if DIS[to]==-1:
DIS[to]=DIS[x]+1
Q.append(to)
EDGE2[x].append(to)
elif DIS[to]==DIS[x]+1:
EDGE2[x].append(to)
if DIS[goal]==-1:
break
# BFSしたときのEDGEを使ってDFSする
MINCOST=[float("inf")]*V
NOW=start
ROUTE=[-1]*V
while NOW!=-1: # DFS
cost=MINCOST[NOW]
if NOW==goal:
ANS+=cost
i=goal
while i!=start: # goalからたどり,Routeを使ってEDGEの更新
j=ROUTE[i]
if EDGE[j][i]==cost:
NOW=j
EDGE2[j].pop()
EDGE[j][i]-=cost # 使ったルートをいけなく更新
MINCOST[j]-=cost
EDGE[i][j]+=cost # 逆向きに進めるようにする.
i=j
continue
if EDGE2[NOW]:
to=EDGE2[NOW][-1]
ROUTE[to]=NOW
MINCOST[to]=min(cost,EDGE[NOW][to])
NOW=to
else:
if NOW==start:
break
EDGE2[ROUTE[NOW]].pop()
NOW=ROUTE[NOW]
ind=0
for i in range(N):
for j in range(M):
if (i+j)%2==1:
for to in EDGE[i*M+j]:
if EDGE[i*M+j][to]==1 and M>1 and to!=goal and to == i*M+j-1:
MAP[i][j]=ALPHA[ind]
MAP[i][j-1]=ALPHA[ind]
ind+=1
elif EDGE[i*M+j][to]==1 and M>1 and to!=goal and to == i*M+j+1:
MAP[i][j]=ALPHA[ind]
MAP[i][j+1]=ALPHA[ind]
ind+=1
elif EDGE[i*M+j][to]==1 and to!=goal and to == i*M+j-M:
MAP[i][j]=ALPHA[ind]
MAP[i-1][j]=ALPHA[ind]
ind+=1
elif EDGE[i*M+j][to]==1 and to!=goal and to == i*M+j+M:
MAP[i][j]=ALPHA[ind]
MAP[i+1][j]=ALPHA[ind]
ind+=1
return ANS,MAP
for i in range(4**(len(LIST)+1)):
if time()-time0>1.9:
break
MAP2=[]
x=i
for j in range(len(LIST)+1):
k=x%4
for c in range(k):
MAP2.append(["#"]*W)
x//=4
if j<len(LIST):
MAP2.append(list(MAP0[LIST[j]]))
if len(MAP2)>H:
break
if len(MAP2)>H:
continue
count=0
for j in range(len(MAP2)):
count+=MAP2[j].count("#")
if count%2==1:
continue
xx,yy=calc(MAP2)
if xx==count//2:
print("Yes")
if len(yy)<H:
rest=H-len(yy)
for _ in range(rest):
A=["."]*W
print("".join(A))
for c in yy:
print("".join(c))
exit()
print("No")
titia