yukicoder No.156 キャンディー・ボックス & No.157 2つの空洞
Cは解けなかったけどいい問題セットだった。問題はこちらから。
No.156 キャンディーボックス
キャンディーがいくつか入った箱がN個ある。キャンディーの数が少ない箱から順番にキャンディーを食べていく。M個食べ終わった時に空になっている箱の数はいくつか。
解法
ある箱に入っているキャンディーが、まだ食べなければいけないキャンディーの数以下なら空となる。これを昇順にソートした箱に対して順番に試していけばいい。
N,M = map(int,raw_input().split()) C = sorted(map(int,raw_input().split())) ans = 0 for i in xrange(N): if M >= C[i]: ans += 1 M -= C[i] print ans
No.157 2つの空洞
WxHの"#"(壁)と"."(空洞) からなる地図を与えられる。地図上には2つの空洞があり、壁をいくつか壊して1つの空洞にしてしまいたい。壊す必要のある壁の最小の数はいくつか。W,H ≦ 20。
解法
まず2つの空洞を区別するためにDFSで空洞をラベル化する(BFSでもOK)。そのあとに4重ループを回して、2つの地点が異なる空洞であるときにそのマンハッタン距離-1を計算し、最小値を取っていけばいい。O(W2 H2)だが制限が小さいので間に合う。他にもいろいろな解法がある教育的な問題ですね。
dxy = zip([1,0,-1,0],[0,1,0,-1]) def rec(x,y,cnt): C[y][x] = str(cnt) for dx,dy in dxy: nx,ny = x+dx,y+dy if 0 <= nx < W and 0 <= ny < H and C[ny][nx] == ".": rec(nx,ny,cnt) W,H = map(int,raw_input().split()) C = [list(raw_input()) for i in xrange(H)] cnt = 0 for y in xrange(H): for x in xrange(W): if C[y][x] == ".": rec(x,y,cnt) cnt += 1 ans = 100000 for y1 in xrange(H): for x1 in xrange(W): for y2 in xrange(H): for x2 in xrange(W): if C[y1][x1] == "0" and C[y2][x2] == "1": ans = min(ans, abs(x1-x2)+abs(y1-y2)) print ans-1