문제풀이/Baekjoon codeplus

백준 Codeplus - 브루트 포스 Part (파이썬 - 2309번,1476번,14500번,9095번,

얄루몬 2021. 6. 29. 12:40

부르트 포스란? 

암호 해독법으로 가능한 모든 문자열을 하나씩 대입해 보는 방식으로 암호를 해독하는 방법이다.

📌출처: https://namu.wiki/w/%EB%B8%8C%EB%A3%A8%ED%8A%B8%20%ED%8F%AC%EC%8A%A4


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

 

2309번: 일곱 난쟁이

아홉 개의 줄에 걸쳐 난쟁이들의 키가 주어진다. 주어지는 키는 100을 넘지 않는 자연수이며, 아홉 난쟁이의 키는 모두 다르며, 가능한 정답이 여러 가지인 경우에는 아무거나 출력한다.

www.acmicpc.net

문제

왕비를 피해 일곱 난쟁이들과 함께 평화롭게 생활하고 있던 백설공주에게 위기가 찾아왔다. 일과를 마치고 돌아온 난쟁이가 일곱 명이 아닌 아홉 명이었던 것이다.

아홉 명의 난쟁이는 모두 자신이 "백설 공주와 일곱 난쟁이"의 주인공이라고 주장했다. 뛰어난 수학적 직관력을 가지고 있던 백설공주는, 다행스럽게도 일곱 난쟁이의 키의 합이 100이 됨을 기억해 냈다.

아홉 난쟁이의 키가 주어졌을 때, 백설공주를 도와 일곱 난쟁이를 찾는 프로그램을 작성하시오.

입력

아홉 개의 줄에 걸쳐 난쟁이들의 키가 주어진다. 주어지는 키는 100을 넘지 않는 자연수이며, 아홉 난쟁이의 키는 모두 다르며, 가능한 정답이 여러 가지인 경우에는 아무거나 출력한다.

출력

일곱 난쟁이의 키를 오름차순으로 출력한다. 일곱 난쟁이를 찾을 수 없는 경우는 없다.

예제 입력 1 복사

20 7 23 19 10 15 25 8 13

예제 출력 1 복사

7 8 10 13 19 20 23

x = []
for i in range(9):
    x.append(int(input()))
sum_x = sum(x)
one = 0
two = 0
for i in range(8):
    for j in range(i + 1, 9):
        if sum_x - (x[i] +x[j]) == 100:
            one = x[i]
            two = x[j]
x.remove(one)
x.remove(two)
x.sort()
for i in x:
    print(i)
            

👽 해설 👽

 

- 빈 리스트를 생성해서 9명의 난쟁이 키값을 for문을 통해서 입력 받아준다.

- sum_x라는 변수를 선언해서 sum(x) 리스트 x의 값을 모두 더한 값을 준비해준다.

- 중첩 반복문을 사용해서 x의 리스트 전체 합을 - 2명 했을 때 100이 된다면 7명의 키가 총 100이 되기 때문에 이 둘을 빼주면 나머지 난쟁이들이 나온다. 

- 이때 x.remove로 두 명의 난쟁이를 제거해준 뒤 리스트 x의 값을 하나씩 for문을 통해서 프린트 해준다. 


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

 

1476번: 날짜 계산

준규가 사는 나라는 우리가 사용하는 연도와 다른 방식을 이용한다. 준규가 사는 나라에서는 수 3개를 이용해서 연도를 나타낸다. 각각의 수는 지구, 태양, 그리고 달을 나타낸다. 지구를 나타

www.acmicpc.net

준규가 사는 나라는 우리가 사용하는 연도와 다른 방식을 이용한다. 준규가 사는 나라에서는 수 3개를 이용해서 연도를 나타낸다. 각각의 수는 지구, 태양, 그리고 달을 나타낸다.

지구를 나타내는 수를 E, 태양을 나타내는 수를 S, 달을 나타내는 수를 M이라고 했을 때, 이 세 수는 서로 다른 범위를 가진다. (1 ≤ E ≤ 15, 1 ≤ S ≤ 28, 1 ≤ M ≤ 19)

우리가 알고있는 1년은 준규가 살고있는 나라에서는 1 1 1로 나타낼 수 있다. 1년이 지날 때마다, 세 수는 모두 1씩 증가한다. 만약, 어떤 수가 범위를 넘어가는 경우에는 1이 된다.

예를 들어, 15년은 15 15 15로 나타낼 수 있다. 하지만, 1년이 지나서 16년이 되면 16 16 16이 아니라 1 16 16이 된다. 이유는 1 ≤ E ≤ 15 라서 범위를 넘어가기 때문이다.

E, S, M이 주어졌고, 1년이 준규가 사는 나라에서 1 1 1일때, 준규가 사는 나라에서 E S M이 우리가 알고 있는 연도로 몇 년인지 구하는 프로그램을 작성하시오.

입력

첫째 줄에 세 수 E, S, M이 주어진다. 문제에 나와있는 범위를 지키는 입력만 주어진다.

출력

첫째 줄에 E S M으로 표시되는 가장 빠른 연도를 출력한다. 1 1 1은 항상 1이기 때문에, 정답이 음수가 나오는 경우는 없다.

예제 입력 1 복사

1 16 16

예제 출력 1 복사

16

예제 입력 2 복사

1 1 1

예제 출력 2 복사

1

예제 입력 3 복사

1 2 3

예제 출력 3 복사

5266

예제 입력 4 복사

15 28 19

예제 출력 4 복사

7980

E, S, M = map(int, input().split())
year = 1



while True:
	# E S M이 16 29 20 일 때 범위를 넘어가는 것으로 1을 출력하고 끝내기 또 year - E S M 이 0이 되면 나눠도 0이 되니 이때도 year = 1 을 프린트하고 브레이크
    if (year - E) % 15 == 0 and (year - S) % 28 == 0 and (year - M) % 19 == 0:
        print(year)
        break
    year += 1

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

 

14500번: 테트로미노

폴리오미노란 크기가 1×1인 정사각형을 여러 개 이어서 붙인 도형이며, 다음과 같은 조건을 만족해야 한다. 정사각형은 서로 겹치면 안 된다. 도형은 모두 연결되어 있어야 한다. 정사각형의 변

www.acmicpc.net

문제

폴리오미노란 크기가 1×1인 정사각형을 여러 개 이어서 붙인 도형이며, 다음과 같은 조건을 만족해야 한다.

  • 정사각형은 서로 겹치면 안 된다.
  • 도형은 모두 연결되어 있어야 한다.
  • 정사각형의 변끼리 연결되어 있어야 한다. 즉, 꼭짓점과 꼭짓점만 맞닿아 있으면 안 된다.

정사각형 4개를 이어 붙인 폴리오미노는 테트로미노라고 하며, 다음과 같은 5가지가 있다.

아름이는 크기가 N×M인 종이 위에 테트로미노 하나를 놓으려고 한다. 종이는 1×1 크기의 칸으로 나누어져 있으며, 각각의 칸에는 정수가 하나 쓰여 있다.

테트로미노 하나를 적절히 놓아서 테트로미노가 놓인 칸에 쓰여 있는 수들의 합을 최대로 하는 프로그램을 작성하시오.

테트로미노는 반드시 한 정사각형이 정확히 하나의 칸을 포함하도록 놓아야 하며, 회전이나 대칭을 시켜도 된다.

입력

첫째 줄에 종이의 세로 크기 N과 가로 크기 M이 주어진다. (4 ≤ N, M ≤ 500)

둘째 줄부터 N개의 줄에 종이에 쓰여 있는 수가 주어진다. i번째 줄의 j번째 수는 위에서부터 i번째 칸, 왼쪽에서부터 j번째 칸에 쓰여 있는 수이다. 입력으로 주어지는 수는 1,000을 넘지 않는 자연수이다.

출력

첫째 줄에 테트로미노가 놓인 칸에 쓰인 수들의 합의 최댓값을 출력한다.

예제 입력 1 

5 5 1 2 3 4 5 5 4 3 2 1 2 3 4 5 6 6 5 4 3 2 1 2 1 2 1

예제 출력 1 

19

예제 입력 2 

4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5

예제 출력 2 

20

예제 입력 3 

4 10 1 2 1 2 1 2 1 2 1 2 2 1 2 1 2 1 2 1 2 1 1 2 1 2 1 2 1 2 1 2 2 1 2 1 2 1 2 1 2 1

예제 출력 3 

7

N,M=map(int, input().split())
maps=[]
for i in range(N):
  maps.append(list(map(int, input().split())))

#가능한 테트로미노를 모두 만들기
tetromino=[[[0,0],[0,1],[0,2],[0,3]], #-
    [[0,0],[1,0],[2,0],[3,0]], #ㅣ
    [[0,0],[0,1],[1,0],[1,1]], #ㅁ
    [[0,0],[0,1],[0,2],[1,0]], #ㄱ
    [[0,0],[0,1],[0,2],[1,2]],
    [[0,0],[1,0],[1,1],[1,2]],
    [[0,2],[1,2],[1,1],[1,0]],
    [[0,1],[0,0],[1,0],[2,0]],
    [[0,0],[0,1],[1,1],[2,1]],
    [[0,0],[1,0],[2,0],[2,1]],
    [[0,1],[1,1],[2,1],[2,0]],
    [[0,0],[0,1],[0,2],[1,1]], #ㅜ
    [[0,1],[1,0],[1,1],[1,2]],
    [[0,0],[1,0],[1,1],[2,0]],
    [[1,0],[0,1],[1,1],[2,1]],
    [[0,1],[1,1],[1,0],[2,0]],
    [[0,0],[1,0],[1,1],[2,1]],
    [[0,1],[0,2],[1,1],[1,0]],
    [[0,0],[0,1],[1,1],[1,2]]]

result=0
for i in range(N):
  for j in range(M):
    for k in tetromino:
      try:
        a=maps[i+k[0][0]][j+k[0][1]]
        b=maps[i+k[1][0]][j+k[1][1]]
        c=maps[i+k[2][0]][j+k[2][1]]
        d=maps[i+k[3][0]][j+k[3][1]]
        temp=a+b+c+d
      except:
        temp=0
      result=max(result,temp)
print(result)

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

 

9095번: 1, 2, 3 더하기

각 테스트 케이스마다, n을 1, 2, 3의 합으로 나타내는 방법의 수를 출력한다.

www.acmicpc.net

정수 4를 1, 2, 3의 합으로 나타내는 방법은 총 7가지가 있다. 합을 나타낼 때는 수를 1개 이상 사용해야 한다.

  • 1+1+1+1
  • 1+1+2
  • 1+2+1
  • 2+1+1
  • 2+2
  • 1+3
  • 3+1

정수 n이 주어졌을 때, n을 1, 2, 3의 합으로 나타내는 방법의 수를 구하는 프로그램을 작성하시오.

입력

첫째 줄에 테스트 케이스의 개수 T가 주어진다. 각 테스트 케이스는 한 줄로 이루어져 있고, 정수 n이 주어진다. n은 양수이며 11보다 작다.

출력

각 테스트 케이스마다, n을 1, 2, 3의 합으로 나타내는 방법의 수를 출력한다.

예제 입력 1 복사

3 4 7 10

예제 출력 1 복사

7 44 274

from sys import stdin

def solution(n):
    if n == 1:
        return 1
    elif n == 2:
        return 2
    elif n == 3:
        return 4
    else:
        return solution(n-1) + solution(n-2) + solution(n-3)

t = int(stdin.readline())
for _ in range(t):
    print(solution(int(stdin.readline())))

👽해설👽

- 1, 2, 3의 합으로 나타내는 방법의 수를 구하는 방법 

- 1일땐 1로만 나타낼 수 있어서 1개 

- 2일땐 (1+1) (2)로 나타낼 수 있어서 2개 

- 3일땐 (1+1+1) (2+1) (1+2) (3)으로 나타낼 수 있어서 4개 

- 4일땐 (1+1+1+1) (1+1+2) (1+2+1) (2+1+1) (3+1) (1+3) (4)로 나타낼 수 있어서 7개