미래의 나를 위한 메모/코딩테스트

[230111] 백준 3085번 - 사탕게임 (Python)

Choi Jaekuk 2023. 1. 11. 09:29

https://github.com/cjk09083/Code

https://www.acmicpc.net/problem/3085

 

3085번: 사탕 게임

예제 3의 경우 4번 행의 Y와 C를 바꾸면 사탕 네 개를 먹을 수 있다.

www.acmicpc.net

 

문제

상근이는 어렸을 적에 "봄보니 (Bomboni)" 게임을 즐겨했다.

가장 처음에 N×N크기에 사탕을 채워 놓는다. 사탕의 색은 모두 같지 않을 수도 있다. 상근이는 사탕의 색이 다른 인접한 두 칸을 고른다. 그 다음 고른 칸에 들어있는 사탕을 서로 교환한다. 이제, 모두 같은 색으로 이루어져 있는 가장 긴 연속 부분(행 또는 열)을 고른 다음 그 사탕을 모두 먹는다.

사탕이 채워진 상태가 주어졌을 때, 상근이가 먹을 수 있는 사탕의 최대 개수를 구하는 프로그램을 작성하시오.

입력

첫째 줄에 보드의 크기 N이 주어진다. (3 ≤ N ≤ 50)

다음 N개 줄에는 보드에 채워져 있는 사탕의 색상이 주어진다. 빨간색은 C, 파란색은 P, 초록색은 Z, 노란색은 Y로 주어진다.

사탕의 색이 다른 인접한 두 칸이 존재하는 입력만 주어진다.

출력

첫째 줄에 상근이가 먹을 수 있는 사탕의 최대 개수를 출력한다.

해답 1) 1076ms 

import sys
input = sys.stdin.readline

def cal(b, n, c):
    cnt = c
    for i in range(n):
        width = 1
        height = 1
        for j in range(n-1):
            if b[i][j] == b[i][j+1]:
                width += 1 
                if width > cnt:
                    cnt = width
            else:
                width = 1

            if b[j][i] == b[j+1][i]:
                height += 1 
                if height > cnt:
                    cnt = height
            else:
                height = 1

    return cnt


if __name__ == "__main__": 
    n = int(input())

    board = [list(map(str, input().rstrip())) for _ in range(n)]

    cnt = 0

    for i in range(n):
        for j in range(n):
            if j + 1 < n and board[i][j] != board[i][j+1]:
                board[i][j], board[i][j+1] = board[i][j+1], board[i][j]
                cnt = cal(board, n, cnt)
                board[i][j], board[i][j+1] = board[i][j+1], board[i][j]

            if i + 1 < n and board[i][j] != board[i+1][j]:
                board[i][j], board[i+1][j] = board[i+1][j], board[i][j]
                cnt = cal(board, n, cnt)
                board[i][j], board[i+1][j] = board[i+1][j], board[i][j]
    print(cnt)
- [i][j] 좌표를 가진 2차원 리스트 생성 (len = n)
- 인접한 두 값을 바꿔가며 (i+1 < n 혹은 j+1 < n 일때) 길이 체크
- 가장 큰 길이를 값으로 제출

 

해답 2) 60ms 

import sys
input = sys.stdin.readline


dx = [-1, 1, 0, 0]
dy = [0, 0, 1, -1]

def cal(x, y):
    width, height = 1,1
    for i in range(4):
        xx, yy = x+dx[i], y+dy[i]

        while 0 <= xx < n and 0 <= yy < n and board[x][y] == board[xx][yy]:
            if dy[i] == 0:
                width += 1
            else :
                height += 1
            xx += dx[i]
            yy += dy[i]

    return max(width, height)


if __name__ == "__main__": 
    n = int(input())
    board = [list(map(str, input().rstrip())) for _ in range(n)]
    # print(*board, sep = "\n")
    cnt = 0

    for i in range(n):
        for j in range(n):
            cnt = max(cnt, cal(i, j))
            if j + 1 < n and board[i][j] != board[i][j+1]:
                board[i][j], board[i][j+1] = board[i][j+1], board[i][j]
                cnt = max(cnt, cal(i, j))
                cnt = max(cnt, cal(i, j+1))
                board[i][j], board[i][j+1] = board[i][j+1], board[i][j]

            if i + 1 < n and board[i][j] != board[i+1][j]:
                board[i][j], board[i+1][j] = board[i+1][j], board[i][j]
                cnt = max(cnt, cal(i, j))
                cnt = max(cnt, cal(i+1, j))
                board[i][j], board[i+1][j] = board[i+1][j], board[i][j]
    print(cnt)
- 바꾼 [i][j]에서 left,right,up,down 방향만 확인하도록 변경