본문 바로가기

알고리즘 삽질장

(228)
[인프런] 스도쿠 검사 문제설명 스도쿠는 9 by 9 크기의 보드가 있을 때, 각 행과 각 열, 그리고 9개의 3 by 3 크기의 보드에 1부터 9까지의 숫자가 중복 없이 나타나도록 보드를 채우면 된다. 예를 들어 다음을 보자. 위 그림은 스도쿠를 정확하게 푼 경우이다. 각 행에 1~9까지의 숫자가 중복 없이 나오고, 각 열에 1~9까지의 숫자가 중복 없이 나오고, 각 3 by 3짜리 사각형(9개이며, 위에서 색깔로 표시되었다)에 1~9까지의 숫자가 중복 없이 나오기 때문이다. 완성된 9 by 9 크기의 스도쿠가 주어지면 정확하게 풀었으면 'YES', 잘 못 풀었으면 'NO'를 출력해라. 입력조건 첫 줄에 완성된 9 by 9 스도쿠가 주어진다. 출력조건 첫 줄에 'YES' 또는 'NO'를 출력한다. 사고과정 중복되지 않고 1~..
[인프런] 봉우리 문제설명 지도 정보가 N by N 격자판에 주어진다. 각 격자에는 그 지역의 높이가 쓰여있다. 각 격자판의 숫자 중 자신의 상,하,좌,우 숫자보다 큰 숫자는 봉우리 지역이다. 봉우리 지역이 몇 개 있는지 알아내는 프로그램을 작성해라. 격자의 가장자리는 0으로 초기화 되었다고 가정한다. 만약 N=5 이고, 격자판의 숫자가 다음과 같다면 봉우리의 개수는 10개이다. 입력조건 첫 줄에 자연수 N(1 arr[x+1][y] and tmp > arr[x][y-1] and tmp > arr[x][y+1]: return True return False n = int(input()) arr = [[0] * (n+2) for _ in range(n+2)] for i in range(n): data = list(map(in..
[인프런] 곳감(모래시계) 문제설명 현수는 곳감을 만들기 위해 감을 깎아 마당에 말리고 있다. 현수의 마당은 N by N 격자판으로 이루어져 있으며, 현수는 각 격자단위로 말리는 감의 수를 정한다. 그런데 해의 위치에 따라 특정 위치의 감은 잘 마르지 않는다. 그래서 현수는 격자의 행을 기준으로 왼쪽, 또는 오른쪽으로 회전시켜 위치를 변경해 모든 감이 잘 마르게 한다. 만약 회전명령 정보가 2, 0, 3 이면 2번째 행을 왼쪽(0)으로 3만큼 아래 그림처럼 회전시키는 명령이다. 첫 번째 수는 행번호, 두 번째 수는 방향인데, 0이면 왼쪽, 1은 오른쪽이고, 세 번째 수는 회전하는 격자의 수이다. M개의 회전명령을 실행하고 난 후 아래와 같이 마당의 모래시계 모양의 영역에는 감이 총 몇개가 있는지 출력하는 프로그램을 작성해라. 입력..
[인프런] 사과나무(다이아몬드) 문제설명 위 그림과 같이 N*N처럼 5*5로 사과나무가 존재할 때, 색깔로 칠해진 사과나무에 존재하는 사과들의 개수 합을 구하여라. 사과들의 개수는 한 칸 내에 있는 값을 의미한다. 사고과정 처음에 어떻게 구현해야 할지 몰랐다... 행을 하나씩 돌면서 시작점, 끝점 인덱스인 s와 e를 변수로 정의해서 풀어야 했다. 이 때, s, e의 초기값은 N을 2로 나눈 몫인 즉, 가장 가운데 지점부터 시작한다. 그래야 다이아몬드의 맨 윗점을 의미하니깐! 그리고 행이 중간까지 갈때까지는 s를 -1, e를 +1해주고 그 이후 행부터는 s를 +1, e를 -1 해주면서 더해야 한다. 풀이(스스로 못 푼 풀이) n = int(input()) arr = [list(map(int, input().split())) for _ ..
[BOJ] 1748번 - 수 이어 쓰기 1 문제설명 https://www.acmicpc.net/problem/1748 1748번: 수 이어 쓰기 1 첫째 줄에 N(1 ≤ N ≤ 100,000,000)이 주어진다. www.acmicpc.net 사고과정 주어지는 데이터 범위 최댓값이 1억이기 때문에 일반 loop문으로 해결해서는 시간 초과가 분명히 발생한다. 따라서 고민을 많이 했는데.. 10의 자릿수(10의 제곱수) 기준으로 분할해서 1억까지의 누적 자릿수 합을 DP 테이블로 미리 만들어 놓고 N이 주어졌을 때, N의 자릿수보다 2보다 작은 인덱스값의 DP 테이블을 참조한다. 그리고 N 자릿수에서 1을 뺀 자릿수의 10의 제곱수와 N의 차이 + 1한 값에다가 N의 자릿수를 곱해주면 N과 동일한 자릿수의 10의 제곱수부터 N까지의 숫자를 붙여놓은 자..
[BOJ] 6064번 - 카잉 달력 문제설명 https://www.acmicpc.net/problem/6064 6064번: 카잉 달력 입력 데이터는 표준 입력을 사용한다. 입력은 T개의 테스트 데이터로 구성된다. 입력의 첫 번째 줄에는 입력 데이터의 수를 나타내는 정수 T가 주어진다. 각 테스트 데이터는 한 줄로 구성된다. www.acmicpc.net 사고과정 처음에 while문으로 하려했으나 시간초과가 발생할 뿐만 아니라 유효하지 않은 경우의 수를 필터링하지 못했다. 그래서 힌트를 보고 DP를 활용해 구현하려 했지만 이것도 모든 테스트를 통과하지 못했다.. 그래서 풀이를 보았는데, 특정 규칙을 찾는 것이 관건이었다. 이 규칙을 찾기 위해서는 "하나만 생각" 하고 "원형 리스트"를 생각하면 될 것 같았다. 여기서 원형 리스트란 무엇이냐? ..
[BOJ] 14500번 - 테트로미노 문제설명 https://www.acmicpc.net/problem/14500 14500번: 테트로미노 폴리오미노란 크기가 1×1인 정사각형을 여러 개 이어서 붙인 도형이며, 다음과 같은 조건을 만족해야 한다. 정사각형은 서로 겹치면 안 된다. 도형은 모두 연결되어 있어야 한다. 정사각형의 변 www.acmicpc.net 사고과정 매우 어려운 문제였다.. 예전에 풀어본 카카오 자물쇠와 열쇠문제처럼 도형을 90도 회전이랑 맵을 모두 이동하면서 확인하나 해야 했다..근데 도형의 좌표값이 고정되어 있어서 역으로 보드 크기를 늘려서 보드를 움직이면서 도형의 좌표값과 일치하는 값들을 구해야 하나도 했다.. 하지만 끝내 구현하지 못했다.. 그래서 풀이를 보니 정말로 노다가 방식으로 도형이 맵에 들어갈 수 있는 모든 ..
[BOJ] 1107번 - 리모컨 문제설명 https://www.acmicpc.net/problem/1107 1107번: 리모컨 첫째 줄에 수빈이가 이동하려고 하는 채널 N (0 ≤ N ≤ 500,000)이 주어진다. 둘째 줄에는 고장난 버튼의 개수 M (0 ≤ M ≤ 10)이 주어진다. 고장난 버튼이 있는 경우에는 셋째 줄에는 고장난 버튼 www.acmicpc.net 사고과정 중복을 허용하는 순열 product 라이브러리를 활용하려고 노력했다. 문제에서 잡아내야 할 포인트들은 다음과 같다. 1. 고장난 숫자 버튼을 제외하고 숫자 순열 경우의 수를 만든 후 +/- 를 사용해서 원하는 채널로 가기 2. 시작채널 100으로부터 +/-만 사용해서 원하는 채널로 가기 3. 문제에서 채널은 무한대까지 있다고 했다. 이를 캐치해야 했어야 함. 주어..
[BOJ] 1476번 - 날짜 계산 문제설명 https://www.acmicpc.net/problem/1476 1476번: 날짜 계산 준규가 사는 나라는 우리가 사용하는 연도와 다른 방식을 이용한다. 준규가 사는 나라에서는 수 3개를 이용해서 연도를 나타낸다. 각각의 수는 지구, 태양, 그리고 달을 나타낸다. 지구를 나타 www.acmicpc.net 사고과정 E, S, M 을 while 무한 루프에서 하나씩 증가시키면서 주어진 E, S, M 과 같아질 때 break하면 된다. 단, 무한 루프 안에서 E, S, M 모두 1일 때 break하는 조건을 먼저 넣어준다. 그리고 s, e, m 과 연도를 1씩 증가시킨 후, s, e, m의 주어진 범위에 넘어가면 1로 바꾸어 준 후, e == E, s == S, m == M인지 조건을 확인한 후 b..
[BOJ] 3085번 - 사탕 게임 문제설명 https://www.acmicpc.net/problem/3085 3085번: 사탕 게임 예제 3의 경우 4번 행의 Y와 C를 바꾸면 사탕 네 개를 먹을 수 있다. www.acmicpc.net 사고과정 브루트 포스 유형인데, 인접한데 다른 사탕인 경우들만 추려서 DFS함수로 개수를 세려고 했다. 그런데 입력예시 정답도 맞지 않고 내 소스코드가 미궁 속으로 빠져버렸다...@@... 1시간 넘게도 안 풀려서 풀이를 보았는데, 풀이는 인접한 사탕이 서로 다르던 아니던 그냥 인접한 사탕은 무조건 두 개를 교환해서 최대 사탕 개수를 계산하였다. 사탕 2개 위치를 교환할 때, 위치 swaping 하는 방법을 생각하지 못했다.. 예전에 정렬알고리즘에서 그렇게 연습했건만... 가로 또는 세로를 살펴본다고 하길..
[BOJ] 2309번 - 일곱 난쟁이 문제설명 https://www.acmicpc.net/problem/2309 2309번: 일곱 난쟁이 아홉 개의 줄에 걸쳐 난쟁이들의 키가 주어진다. 주어지는 키는 100을 넘지 않는 자연수이며, 아홉 난쟁이의 키는 모두 다르며, 가능한 정답이 여러 가지인 경우에는 아무거나 출력한다. www.acmicpc.net 사고과정 모든 경우의 수를 다 시험해보는 부르트 포스 유형이다. 그 중에서 조합 라이브러리를 사용했다. 키 합이 100이 되는 난쟁이들을 찾는 순간 바로 break 했다. 풀이 from itertools import combinations array = [int(input()) for _ in range(9)] for comb in list(combinations(array, 7)): height..
[BOJ] 17404번 - RGB거리 2 문제설명 https://www.acmicpc.net/problem/17404 17404번: RGB거리 2 첫째 줄에 집의 수 N(2 ≤ N ≤ 1,000)이 주어진다. 둘째 줄부터 N개의 줄에는 각 집을 빨강, 초록, 파랑으로 칠하는 비용이 1번 집부터 한 줄에 하나씩 주어진다. 집을 칠하는 비용은 1,000보다 작거나 www.acmicpc.net 사고과정 RGB 거리 문제와 비슷한 유형이긴 했지만 첫 집과 마지막 집 조건이 달라야 하는 조건이 추가 되었다. 이를 어떻게 처리할 수 있을지 매우 고민했다..처음에 DP 테이블 요소에 맨 처음 집 위치를 넣어주어야 하나 싶었는데 너무 복잡해지는 것 같아 아닌 것 같았다.. 풀이를 보니 처음 집의 색깔 3종류에 따라 개별로 탐색을 수행했다. 문제를 푸는 단계..
[BOJ] 2133번 - 타일 채우기 문제설명 https://www.acmicpc.net/problem/2133 2133번: 타일 채우기 3×N 크기의 벽을 2×1, 1×2 크기의 타일로 채우는 경우의 수를 구해보자. www.acmicpc.net 사고과정 개인적으로 너무 어려웠다. 간단하다고 생각했는데, 타일과 주어진 틀의 세로길이가 딱맞아떨어지지 않다 보니까 추가로 생기는 경우의 수를 어떻게 해야 할지 몰랐다.. 구글링을 해보니 다른 분의 좋은 풀이를 참고해서 풀었다. 핵심은 '가로 길이가 2인 타일'에 포커스를 맞춰서 점화식을 세우는 것인데, 가로 길이가 2, 4, 6, ..., $i$(2의 배수일 때)인 경우를 매번 고려해야 한다. 잘 이해가 안간다면 여기 풀이를 참고하자..! 그림을 그려주신 풀이도 있다!(감사합니다) 풀이(스스로 못..
[BOJ] 13398번 - 연속합 2 문제설명 https://www.acmicpc.net/problem/13398 13398번: 연속합 2 첫째 줄에 정수 n(1 ≤ n ≤ 100,000)이 주어지고 둘째 줄에는 n개의 정수로 이루어진 수열이 주어진다. 수는 -1,000보다 크거나 같고, 1,000보다 작거나 같은 정수이다. www.acmicpc.net 사고과정 1차원 리스트 DP 테이블로 풀려고 하니 시간초과가 발생했다. 2차원 리스트를 사용해야 하는데 어떻게 사용할지 아이디어가 떠오르지 않았다.. 풀이를 보니, 문제에거 1개의 원소만 삭제할 수 있다고 했으니 DP 테이블을 2차원으로 두되, 첫 번째 행의 DP 테이블은 1개의 원소를 제거할 여지가 남아있는 경우, 두 번째 행은 제거하지 않고 그대로 갈 경우로 두고 진행했다. 그리고 DP ..
[BOJ] 11054번 - 가장 긴 바이토닉 부분 수열 문제설명 https://www.acmicpc.net/problem/11054 11054번: 가장 긴 바이토닉 부분 수열 첫째 줄에 수열 A의 크기 N이 주어지고, 둘째 줄에는 수열 A를 이루고 있는 Ai가 주어진다. (1 ≤ N ≤ 1,000, 1 ≤ Ai ≤ 1,000) www.acmicpc.net 사고과정 문제에서 설명하는 바이토닉 부분 설명 정의에 의해서 주어진 수열 안에서 증,감하고 다시 증가하는 부분을 캐치해서 수열의 길이를 구해야 하는 건지 복잡했다.. 결국 풀지 못하고 구글링을 염탐했다.. 풀이를 보니 주어진 수열을 가장 긴 증가하는 부분 수열 길이, 가장 긴 감소하는 부분 수열 길이 별로 DP테이블을 따로 구한 후, 이 두 DP 테이블 간의 동일한 인덱스에 있는 두 수의 합이 바로 바이토..
[BOJ] 11722번 - 가장 긴 감소하는 부분 수열 문제설명 https://www.acmicpc.net/problem/11722 11722번: 가장 긴 감소하는 부분 수열 수열 A가 주어졌을 때, 가장 긴 감소하는 부분 수열을 구하는 프로그램을 작성하시오. 예를 들어, 수열 A = {10, 30, 10, 20, 20, 10} 인 경우에 가장 긴 감소하는 부분 수열은 A = {10, 30, 10, 20, 20, 10} www.acmicpc.net 사고과정 가장 긴 증가하는 부분 수열을 찾는 LIS 알고리즘을 이용하되 주어진 배열을 reverse 해서 LIS를 적용하거나 LIS 알고리즘 내부의 부등호를 반대로 바꾸어주면 된다. 예전에도 관련 문제를 풀어봐서 수월히 해결했다. 풀이 n = int(input()) array = list(map(int, input..
[BOJ] 11055번 - 가장 큰 증가 부분 수열 문제설명 https://www.acmicpc.net/problem/11055 11055번: 가장 큰 증가 부분 수열 수열 A가 주어졌을 때, 그 수열의 증가 부분 수열 중에서 합이 가장 큰 것을 구하는 프로그램을 작성하시오. 예를 들어, 수열 A = {1, 100, 2, 50, 60, 3, 5, 6, 7, 8} 인 경우에 합이 가장 큰 증가 부분 수 www.acmicpc.net 사고과정 LIS 알고리즘을 활용하는데, 문제에서 요구하는 것은 증가하는 부분 수열의 합이 가장 큰 것을 구하는 것이다. 무의식적으로 그냥 증가 부분 수열의 길이를 DP 테이블에 넣고 삽질하고 있었다.. 문제에서 요구하는 것은 길이가 아닌 수열의 합이므로 DP 테이블에는 수열의 길이가 아닌 수열의 각 번째 자리에서 나올 수 있는 ..
[BOJ] 2156번 - 포도주 시식 문제설명 https://www.acmicpc.net/problem/2156 2156번: 포도주 시식 효주는 포도주 시식회에 갔다. 그 곳에 갔더니, 테이블 위에 다양한 포도주가 들어있는 포도주 잔이 일렬로 놓여 있었다. 효주는 포도주 시식을 하려고 하는데, 여기에는 다음과 같은 두 가지 규 www.acmicpc.net 사고과정 연습장에 그려가며 규칙을 발견하려고 했다. 다음 포도주의 입장에서 생각하여 N번째 포도주를 마실 경우와 마시지 않을 경우를 생각해보았다. 그런데 연속해서 3잔이상은 못마신다는 조건 때문에 약간 복잡해졌다.. 그래서 포도주 array 따로 DP 테이블 따로 1차원 리스트를 2개로 운영해야 할 것 같았다.. N = 4일때까지 경우의 수를 구했음에도 점화식이 헷갈렸다.. 포도주 arra..
[BOJ] 9465번 - 스티커 문제설명 https://www.acmicpc.net/problem/9465 9465번: 스티커 첫째 줄에 테스트 케이스의 개수 T가 주어진다. 각 테스트 케이스의 첫째 줄에는 n (1 ≤ n ≤ 100,000)이 주어진다. 다음 두 줄에는 n개의 정수가 주어지며, 각 정수는 그 위치에 해당하는 스티커의 www.acmicpc.net 사고과정 스티커가 좌우에 인접해서 떨어지기 때문에 같은 선분은 공유해선 안된다. 따라서 N = 1일 때까지는 바로 직전의 대각선 스티커와 더하되 N = 2번째 일 때부터는 바로 직전의 대각선을 더할 것인지 2칸 이전의 대각선을 더할 것인지 중에 최댓값을 선택하면 된다. 처음에 점화식을 잘 세웠다고 생각했는데, 에러가 발생했다.. 그래서 오히려 이상한 사고의 길로 들어섰다.....
[BOJ] 11057번 - 오르막 수 문제설명 https://www.acmicpc.net/problem/11057 11057번: 오르막 수 오르막 수는 수의 자리가 오름차순을 이루는 수를 말한다. 이때, 인접한 수가 같아도 오름차순으로 친다. 예를 들어, 2234와 3678, 11119는 오르막 수이지만, 2232, 3676, 91111은 오르막 수가 아니다. 수 www.acmicpc.net 사고과정 이 문제도 DP 테이블을 2차원 리스트로 정의해야 한다. 이 때, 행($i$)는 N을, 열($j$)는 가장 앞에 오는 숫자 0~9를 의미한다. 결국 DP 테이블에 들어가는 값은 앞에오는 숫자가 0~9 중 하나일 때, 만들 수 있는 오르막 수 개수를 의미한다. N = 1일 때는 즉, 0~9까지 모두 1개밖에 존재하지 않는다. N = 2일 때는 앞..