JOI2011本戦A 惑星探索

この記事で使うアルゴリズム

幅優先探索

はじめに

カテゴリー競プロ初中級者100問では、Qiitaにて@e869120さんがレッドコーダーが教える、競プロ・AtCoder上達のガイドライン【中級編:目指せ水色コーダー!】としてまとめられている100問をPythonで解いています。

全問題の一覧はこちらです

問題

https://atcoder.jp/contests/joi2011ho/tasks/joi2011ho1
https://www.ioi-jp.org/joi/2010/2011-ho-tasks_data/2011-ho.pdf#page=2

この問題は累積和で解くことができます。

方針

二次元の累積和を求めます。

コード

想定解法で実装していますがPythonの場合TLEとなります。メモリ使用量が大きいため、PyPyではMLEとなります。PythonでのACがほぼ存在しないため、Pythonで取り組むのは難しい問題でした。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import itertools
def transpose(mat): # 二次元のリストを転置する関数
return list(zip(*mat))
M, N = map(int, input().split())
K = int(input())
A = []
for m in range(M):
a = input()
A.append(a)

J = [[0] * (N+1) for _ in range(M+1)]
O = [[0] * (N+1) for _ in range(M+1)]
I= [[0] * (N+1) for _ in range(M+1)]

for m in range(M):
for n in range(N):
if A[m][n]=='J':
J[m+1][n+1] = 1
elif A[m][n] == 'O':
O[m+1][n+1] = 1
else:
I[m+1][n+1] = 1


def calc_csum_mat(A):
B = []
for a in A:
csum = list(itertools.accumulate(a))
B.append(csum)
B = transpose(B)

csum_mat = []
for a in B:
csum = list(itertools.accumulate(a))
csum_mat.append(csum)
csum_mat = transpose(csum_mat)
return csum_mat

J = calc_csum_mat(J)
O = calc_csum_mat(O)
I = calc_csum_mat(I)
query = []
def calc_csum(mat,a,b,c,d):
a -= 1
b -= 1
return str(mat[c][d] - mat[c][b] - mat[a][d] + mat[a][b])
for k in range(K):
query.append(list(map(int,input().split())))
for q in query:
a,b,c,d = q
print (calc_csum(J,a,b,c,d) + ' ' + calc_csum(O,a,b,c,d) + ' ' + calc_csum(I,a,b,c,d))

記事情報

  • 投稿日:2020年6月20日
  • 最終更新日:2020年6月20日