AOJ ALDS1_3_D Areas on the Cross-Section Diagram
備忘録
問題
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_3_D&lang=ja
回答
import sys, os, math, bisect, itertools, collections, heapq, queue # from scipy.sparse.csgraph import csgraph_from_dense, floyd_warshall from decimal import Decimal from collections import defaultdict, deque import copy sys.setrecursionlimit(10000000) ii = lambda: int(sys.stdin.buffer.readline().rstrip()) il = lambda: list(map(int, sys.stdin.buffer.readline().split())) fl = lambda: list(map(float, sys.stdin.buffer.readline().split())) iln = lambda n: [int(sys.stdin.buffer.readline().rstrip()) for _ in range(n)] iss = lambda: sys.stdin.buffer.readline().decode().rstrip() sl = lambda: list(map(str, sys.stdin.buffer.readline().decode().split())) isn = lambda n: [sys.stdin.buffer.readline().decode().rstrip() for _ in range(n)] lcm = lambda x, y: (x * y) // math.gcd(x, y) MOD = 10 ** 9 + 7 MAX = float('inf') def main(): if os.getenv("LOCAL"): sys.stdin = open("input.txt", "r") S = iss() stack = [] water = [] sum = 0 for i in range(len(S)): s = S[i] if s == '\\': stack.append(i) elif s == '/' and len(stack) > 0: j = stack.pop() sum += i - j area = i - j while len(water) > 0 and water[-1][0] > j: w = water.pop() area += w[1] water.append([j, area]) ret = [] for i, w in water: ret.append(w) print(sum) print(len(ret), *ret) if __name__ == '__main__': main()
考え方
螺旋本より、スタックの問題。
実装はC++のコードをほぼ写経。。。
観点は2つで、
1つ目は/
に対応する\
との面積を求めること、
2つ目は、深さが2以上ある場合(例えば\\//
など)の時、
1つの水たまりとして扱うこと。
1つ目について。
\
が与えられたとき、そのindexをスタックに積んでおく。
/
が与えられたとき、スタックから1つpopすることで、
/
に対応する\
の位置が判明する。
あとは自身(/
)の位置から対応する\
の位置で面積を求めることが出来る。
(全て1 * 1
の区画として扱われるため、/
の位置 - \
の位置で面積を求めることが出来る)
2つ目について。
予め、1つ目で得た\
の位置と面積を別のスタックに積んでおく。
新たに位置と面積の情報をスタックで積む際に、
スタックの末尾に自分の\
の位置より大きい値の有無を確認する。
自分の\
の位置より大きいとは、自分より右側に存在しているため、
1つの繋がった水たまりと判定することができる。