[python]白駿20061モノラル2チャネル

36610 ワード

https://www.acmicpc.net/problem/20061
「モノラルモノラルモノラルモノラルモノラルモノラルモノラルモノラルモノラルモノラルモノラルモノラルモノラルモノラルモノラルモノラルモノラルモノラルモノラルモノラルモノラルモノラルモノラルモノラルモノラルモノラルモノラル碁盤は赤、青、緑の碁盤が図のようにくっついている形態です.ゲームで使用する座標(x,y)では,xは行,yは列を表す.赤、青、緑の板で使用される座標は、その色で図に書かれています.
以下省略
行または列がタイルで満たされると、浅いセルに塊がある場合が同時に発生する可能性があります.この場合、行や列がタイルで満たされていない場合、点数を得る過程がすべて行われた後、軟格子に塊がある場合を処理すべきである.
ブロックをボードに置くと、他のブロックとマージされません.ブロックを置く位置を順番に並べた場合,得られた点数と緑色と青色の碁盤にタイルがある格子数を求める.
入力
1行目にブロックを配置した回数N(1≦N≦10000).
2行目から、N行にブロックを配置する情報は、txyと同じ順序で1行ずつ与えられる.
t=1:サイズ1×シングルブロックを(x,y)に置く
t=2:サイズ1×ダブルブロックを(x,y)、(x,y+1)に配置します.
t=3:サイズ2×シングルブロックを(x,y)、(x+1,y)に配置します.
ブロックが占めるセルが赤いセルの境界を超えている場合は、入力は与えられません.
しゅつりょく
最初の行にすべてのブロックを配置したときに得られたスコアを出力します.
2行目は、青い板と緑の板のタイルがあるセルの数を出力します.
入力例1
1
1 1 1
サンプル出力1
0
2
図3のように.
入力例6
7
1 1 1
2 3 0
3 2 2
3 2 3
3 1 3
2 0 0
3 2 0
サンプル出力6
1
18
図10のように.
入力例7
8
1 1 1
2 3 0
3 2 2
3 2 3
3 1 3
2 0 0
3 2 0
3 1 2
サンプル出力7
2
15
図13のように.
コード#コード#
# 20061 모노미노도미노 2

# t 모양: ㅇ, ㅡ, ㅣ
def blue_insert(t, x):
    c_idx = 0
    r = x
    if t == 1:
        while blue[r][c_idx] == 0 and c_idx < 5:
            c_idx += 1
        if blue[r][c_idx] == 1:
            c_idx -= 1

    elif t == 2:
        while blue[r][c_idx] == 0 and blue[r][c_idx + 1] == 0 and c_idx < 4:
            c_idx += 1
        if blue[r][c_idx] == 1 or blue[r][c_idx + 1] == 1:
            c_idx -= 1
        blue[r][c_idx + 1] = 1

    elif t == 3:
        while blue[r][c_idx] == 0 and blue[r + 1][c_idx] == 0 and c_idx < 5:
            c_idx += 1
        if blue[r][c_idx] == 1 or blue[r + 1][c_idx] == 1:
            c_idx -= 1
        blue[r + 1][c_idx] = 1

    blue[r][c_idx] = 1


def get_blue_score():
    cnt = 0
    for c in range(2, 6):
        for r in range(4):
            if blue[r][c] == 0:
                break
        else:
            cnt += 1
            for r in range(4):
                blue[r][c] = 0

            # 터진 것 채우기
            for temp_c in range(c, 0, -1):
                for r in range(4):
                    blue[r][temp_c] = blue[r][temp_c - 1]
                    blue[r][temp_c - 1] = 0

    return cnt


def push_blue():
    global blue
    cur_c = -1
    for c in range(2):
        for r in range(4):
            if blue[r][c] == 1:
                cur_c = c
                break
        if cur_c != -1:
            break
    # 밝은 곳에 숫자가 없으면 return
    if cur_c == -1:
        return

    temp_blue = [[0] * 6 for _ in range(4)]
    push_num = 0
    # 두 칸 밀기
    if cur_c == 0:
        push_num = 2
    # 한 칸 밀기
    elif cur_c == 1:
        push_num = 1

    for c in range(2, 6):
        for r in range(4):
            temp_blue[r][c] = blue[r][c - push_num]

    blue = [temp[:] for temp in temp_blue]


# t 모양: ㅇ, ㅡ, ㅣ
def green_insert(t, y):
    r_idx = 0
    c = y
    if t == 1:
        while green[r_idx][c] == 0 and r_idx < 5:
            r_idx += 1
        if green[r_idx][c] == 1:
            r_idx -= 1

    elif t == 2:
        while green[r_idx][c] == 0 and green[r_idx][c + 1] == 0 and r_idx < 5:
            r_idx += 1
        if green[r_idx][c] == 1 or green[r_idx][c + 1] == 1:
            r_idx -= 1
        green[r_idx][c + 1] = 1

    elif t == 3:
        while green[r_idx][c] == 0 and green[r_idx + 1][c] == 0 and r_idx < 4:
            r_idx += 1
        if green[r_idx][c] == 1 or green[r_idx + 1][c] == 1:
            r_idx -= 1
        green[r_idx + 1][c] = 1

    green[r_idx][c] = 1


def get_green_score():
    cnt = 0
    for r in range(2, 6):
        for c in range(4):
            if green[r][c] == 0:
                break
        else:
            cnt += 1
            for c in range(4):
                green[r][c] = 0
            
            # 터진 것 채우기
            for temp_r in range(r, 0, -1):
                for c in range(4):
                    green[temp_r][c] = green[temp_r - 1][c]
                    green[temp_r - 1][c] = 0

    return cnt


def push_green():
    global green
    cur_r = -1
    for r in range(2):
        for c in range(4):
            if green[r][c] == 1:
                cur_r = r
                break
        if cur_r != -1:
            break

    # 밝은 곳에 숫자가 없으면 return
    if cur_r == -1:
        return

    temp_green = [[0] * 4 for _ in range(6)]
    push_num = 0
    # 두 칸 밀기
    if cur_r == 0:
        push_num = 2
    # 한 칸 밀기
    elif cur_r == 1:
        push_num = 1

    for r in range(2, 6):
        for c in range(4):
            temp_green[r][c] = green[r - push_num][c]

    green = [temp[:] for temp in temp_green]


N = int(input())

blue = [[0] * 6 for _ in range(4)]
green = [[0] * 4 for _ in range(6)]
score = 0

for _ in range(N):
    t, x, y = map(int, input().split())

    # Blue에 블록 넣기
    blue_insert(t, x)
    # 점수 획득
    score += get_blue_score()
    # 연한 칸 블록 있으면 밀기
    push_blue()


    # Green에 블록 넣기
    green_insert(t, y)
    # 점수 획득
    score += get_green_score()
    # 연한 칸 블록 있으면 밀기
    push_green()

block_cnt = 0
# 파란색 타일 갯수 세기

for r in range(4):
    for c in range(2, 6):
        if blue[r][c] == 1:
            block_cnt += 1

# 초록색 타일 갯수 세기
for r in range(2, 6):
    for c in range(4):
        if green[r][c] == 1:
            block_cnt += 1

print(score)
print(block_cnt)

ずれ
スコアを取得した後、爆発した行/列の上部/左側のブロックが引き出されなかったため、コミット後にエラーが発生しました.見えます.
入力エラーの例
4
2 3 0
2 3 0
2 1 0
2 1 2
上の項目だけ修正すれば正解です.
三星電子製品の発売問題を見て、実施/シミュレーションアルゴリズムを繰り返し解き、実現能力がますます強くなり、所要時間が少なくなっている.
効果的に関数を作るスキルも増えています.
がんばって!