競プロ典型 90 問 004 - Cross Sum(★2)
競プロの初めて向けの10問を解いたので、90問をチャレンジ!
★2でもめちゃくちゃ難しいんよな。。。
問題
H 行
W 列のマス目があります。
その縦横の合計を出してほしい。
説明
縦横の合計を足すのですが、
重複しているところを引くことが必要になります。これを包除原理というらしい。
H行とW列を足しても、重複があるため、(H+W)-1 が成り立つ。
Aは[[1,2,3],[1,2,3],[4,5,6]]みたいなリスト。
前処理として、縦のみ。横のみのリストを作成する。
zip(*A)
zipは*演算子を使えば展開してくれる。
リストを展開して、各リストの要素を対応するものとして組み合わせる。
各リストの同じインデックス同士が組み合わさるみたい。
→各リストの同じインデックスインデックス同士という事は縦軸で合わさる。
縦の合計ができる。
参考:
https://qiita.com/kubochiro/items/5daedd51654a8155bc06
ソースコード
# 入力
H, W = map(int, input().split())
A = [list(map(int, input().split())) for _ in range(H)]
# 前処理
yoko = list(map(sum, A))
tate = list(map(sum, zip(*A)))
yoko = list(map(sum,A))
tate = list(map(sum,zip(*A)))
for i in range(H):
print(
' '.join(
map(lambda j: str(yoko[i]+ tate[j] - A[i][j]) ,range(W))
)
)
##########
range(H)で縦を回す。range(W)で横を回す。
mapだけでは、for i in range(H)を回すだけ。
mapのrange(W)で横も回す。mapの中でfor文書いてもう一回回しているイメージでいます。
range(H)だけでは、行しか回れない。
mapは行数分しか回せないが、mapの中でrange(W)することで、縦x横になる。
あとは、提出用のデータを作るために、strに変換してjoinで文字結合する。
参考:
https://drken1215.hatenablog.com/entry/2021/07/25/215000