문제:

풀이방법:

생각보다 시간에 대한 조건이 넉넉한 편이기 때문에 모든 경우의 수를 확인하면서 풀어도 된다.

가능한 모든 경우의 수를 구하기 위해서 key와 lock의 크기를 기준으로 a라는 배열을 만든다. key와 lock의 크기가 3x3으로 동일하다고 하면 다음과 같이 a를 만들어야 한다.

위 그림에서 노란색으로 색칠한 부분이 lock에 해당하고, 빨간색 박스가 key에 해당한다. 이제 이 배열에서 빨간색 박스 key로 a를 슬라이딩하면서 lock에 해당하는 부분이 모두 채워지는 경우가 있는지 확인하면 된다.

따라서 a를 (len(key)*2+len(lock)-2)x(len(key)*2+len(lock)-2) 크기인 0인 2차원 배열로 초기화 하고 lock에 해당하는 부분만 채워주도록 한다.

위 그림부터 시작해서 현재 key 모양, 90도 회전한 모양, 180도 회전한 모양, 270도 회전한 모양을 각각 넣어보면서(360도는 현재 key 모양과 같다.) lock의 모든 값이 1로 바뀌었는지 확인한다.

이 확인 과정을 슬라이딩 끝까지 진행하며 중간에 True인 경우가 있다면 바로 true를 반환한다. 만약 끝까지 true인 경우가 없다면 false를 반환한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import copy
 
def check(x,y,a,key,x1,y1,lock):
    temp=copy.deepcopy(a)
    for i in range(len(key)):
        for j in range(len(key)):
            temp[x+i][y+j]+=key[i][j]
    if solve(x1,y1,temp,lock):
        return True
    else:
        return False
 
def solve(x,y,a,lock):
    for i in range(len(lock)):
        for j in range(len(lock)):
            if a[x+i][y+j]==0 or a[x+i][y+i]==2:
                return False
    return True
 
def rotate_90(m):
    N = len(m)
    ret = [[0* N for _ in range(N)]
    for r in range(N):
        for c in range(N):
            ret[c][N-1-r] = m[r][c]
    return ret
 
def rotate_180(m):
    N = len(m)
    ret = [[0* N for _ in range(N)]
    for r in range(N):
        for c in range(N):
            ret[N-1-r][N-1-c] = m[r][c]
    return ret
 
def rotate_270(m):
    N = len(m)
    ret = [[0* N for _ in range(N)]
 
    for r in range(N):
        for c in range(N):
            ret[N-1-c][r] = m[r][c]
    return ret
 
def solution(key,lock):
    a=[[0 for i in range(len(key)*2+len(lock)-2)]for i in range(len(key)*2+len(lock)-2)]
    x=len(key)-1
    y=len(key)-1
    for i in range(len(lock)):
        for j in range(len(lock)):
            a[x+i][y+j]=lock[i][j]
    for i in range(len(a)-len(key)+1):
        for j in range(len(a)-len(key)+1):
            if check(i,j,a,key,x,y,lock):
                return True
            key90=rotate_90(key)
            if check(i,j,a,key90,x,y,lock):
                return True
            key180=rotate_180(key)
            if check(i,j,a,key180,x,y,lock):
                return True
            key270=rotate_270(key)
            if check(i,j,a,key270,x,y,lock):
                return True
    return False
cs

문제링크:

https://programmers.co.kr/learn/courses/30/lessons/60059

 

코딩테스트 연습 - 자물쇠와 열쇠

[[0, 0, 0], [1, 0, 0], [0, 1, 1]] [[1, 1, 1], [1, 1, 0], [1, 0, 1]] true

programmers.co.kr

 

'Algorithm > Python' 카테고리의 다른 글

[BOJ]14502. 연구소  (0) 2020.08.18
[BOJ]2961. 도영이가 만든 맛있는 음식  (0) 2020.08.13
[BOJ]2493. 탑  (0) 2020.08.06
[BOJ]19532. 수학은 비대면강의입니다.  (0) 2020.08.04
[BOJ]2580. 스도쿠  (0) 2020.07.30

문제:

1부터 N까지의 수를 이어서 쓰면 다음과 같이 새로운 하나의 수를 얻을 수 있다.

 

1234567891011121314151617181920212223...

 

이렇게 만들어진 새로운 수는 몇 자리 수일까? 이 수의 자릿수를 구하는 프로그램을 작성하시오.

입력:

첫째 줄에 N(1<=N<=100,000,000)이 주어진다.

출력:

첫째 줄에 새로운 수의 자릿수를 출력한다.

풀이방법:

처음에는 브루트 포스로 알고리즘 분류가 되어 있어서 그냥 N까지의 수를 다 붙인 다음에 길이를 구하는 방식으로 했는데 시간초과가 발생했다.

1
2
3
4
5
6
#시간초과
n=int(input())
answer=''
for i in range(1,n+1):
    answer+=str(i)
print(len(answer))
cs

그래서 처음 받은 N을 기준으로 자릿수를 줄여나가면서 더하는 방식으로 바꾸어서 해결을 했다.

ex) 3자리수의 갯수*3 + 2자리수의 갯수*2 ....

1
2
3
4
5
6
7
8
9
n=input()
 
answer=0
length=len(n)
while length:
    answer+=(int(n)-10**(length-1)+1)*length
    n=10**(length-1)-1
    length-=1
print(answer)
cs

문제링크:

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

 

1748번: 수 이어 쓰기 1

첫째 줄에 N(1≤N≤100,000,000)이 주어진다.

www.acmicpc.net

 

'Algorithm > Python' 카테고리의 다른 글

[BOJ]2644. 촌수계산  (0) 2020.03.24
[BOJ]2352. 반도체 설계  (0) 2020.03.19
[BOJ]1267. 핸드폰 요금  (0) 2020.03.12
[BOJ]2579. 계단 오르기  (0) 2020.03.10
[BOJ]13458. 시험 감독  (0) 2020.03.05

문제:

N개의 정수로 이루어진 수열이 있을 때, 크기가 양수인 부분수열 중에서 그 수열의 원소를 다 더한 값이 S가 되는 경우의 수를 구하는 프로그램을 작성하시오.

입력:

첫째 줄에 정수의 개수를 나타내는 N과 정수 S가 주어진다. (1<=N<=20, |S|<=1,000,000) 둘째 줄에 N개의 정수가 빈 칸을 사이에 두고 주어진다. 주어지는 정수의 절댓값은 100,000을 넘지 않는다.

출력:

첫째 줄에 합이 S가 되는 부분수열의 개수를 출력한다.

풀이방법:

알고리즘 분류가 브루트 포스로 되어 있었기 때문에 가능한 모든 경우의 수를 만들고자 하였다. 따라서 itertools의 combinations을 사용하였다. itertools.combinations( iterable, n)과 같이 사용하며 iterable한 객체로 반환을 한다. 따라서 이를 반복문으로 넣고 합했을 때 s가 되는 경우에 answer를 하나씩 올렸다.

1
2
3
4
5
6
7
8
9
10
11
12
13
import itertools
 
n,s=map(int,input().split())
numbers=list(map(int,input().split()))
 
answer=0
for i in range(1,n+1):
    for c in itertools.combinations(numbers,i):
        if s == sum(c):
            answer+=1
            
            
print(answer)
cs

문제링크:

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

 

1182번: 부분수열의 합

첫째 줄에 정수의 개수를 나타내는 N과 정수 S가 주어진다. (1 ≤ N ≤ 20, |S| ≤ 1,000,000) 둘째 줄에 N개의 정수가 빈 칸을 사이에 두고 주어진다. 주어지는 정수의 절댓값은 100,000을 넘지 않는다.

www.acmicpc.net

 

'Algorithm > Python' 카테고리의 다른 글

[BOJ]13305. 주유소  (0) 2020.02.25
[BOJ]2485. 가로수  (0) 2020.02.20
[BOJ]1431. 시리얼 번호  (1) 2020.02.13
[BOJ]6603. 로또  (0) 2020.02.11
[BOJ]1297. TV 크기  (0) 2020.02.06

문제:

미세먼지를 제거하기 위해 구사과는 공기청정기를 설치하려고 한다. 공기청정기의 성능을 테스트하기 위해 구사과는 집을 크기가 RxC인 격자판으로 나타냈고, 1x1 크기의 칸으로 나눴다. 구사과는 뛰어난 코딩 실력을 이용해 각 칸 (r,c)에 있는 미세먼지의 양을 실시간으로 모니터링하는 시스템을 개발했다. (r,c)는 r행 c열을 의미한다.

 

공기청정기는 항상 왼쪽 열에 설치되어 있고, 크기는 두 행을 차지한다. 공기청정기가 설치되어 있지 않은 칸에는 미세먼지가 있고, (r,c)에 있는 미세먼지의 양은 Ar,c 이다.

 

1초 동안 적힌 일이 순서대로 일어난다.

1. 미세먼지가 확산된다. 확산은 미세먼지가 있는 모든 칸에서 동시에 일어난다.

 - (r,c)에 있는 미세먼지는 인접한 네 방향으로 확산된다.

 - 인접한 방향에 공기청정기가 있거나, 칸이 없으면 그 방향으로는 확산이 일어나지 않는다.

 - 확산되는 양은 Ar,c / 5 이고 소주점은 버린다.

 - (r,c)에 남은 미세먼지의 양은 Ar,c - (Ar,c/5)x(확산된 방향의 개수) 이다.

2. 공기청정기가 작동한다.

 - 공기청정기에는 바람이 나온다.

 - 위쪽 공기청정기의 바람은 반시계방향으로 순환하고, 아래쪽 공기청정기의 바람은 시계방향으로 순환한다.

 - 바람이 불면 미세먼지가 바람의 방향대로 모두 한 칸씩 이동한다.

 - 공기청정기에서 부는 바람은 미세먼지가 없는 바람이고, 공기청저기로 들어간 미세먼지는 모두 정화된다.

 

다음은 확산의 예시이다.

공기청정기의 바람은 다음과 같은 방향으로 순환한다.

방의 정보가 주어졌을 때, T초가 지난 후 구사과의 방에 남아있는 미세먼지의 양을 구해보자.

입력:

첫째 줄에 R, C, T (6<=R,C<=50,1<=T<=1,000) 가 주어진다.

 

둘째 줄부터 R개의 줄에 Ar,c(-1<=Ar,c<=1,000)가 주어진다. 공기청정기가 설치된 곳은 Ar,c 가 -1이고, 나머지 값은 미세먼지의 양이다. -1은 2번 위아래로 붙어져 있고, 가장 윗 행, 아랫 행과 두 칸이상 떨어져 있다.

출력:

첫째 줄에 T초가 지난 후 구사과 방에 남아있는 미세먼지의 양을 출력한다.

풀이방법:

크게 두 함수로 구성되어 있다. 미세먼지가 확산되는 것을 나타내는 Spread와, 공기청정기가 작동하는 Clean()으로 구성되어 있었다. 매 초마다 Spread와 Clean이 반복된다.

Spread에서는 확산 될 때, 동시에 모든 곳에서 주변으로 퍼지기 때문에 nextD라는 빈 배열을 만들어서 이 곳에 값을 더하는 방식으로 했다.

Clean에서는 브루트포스 방식으로 진행했다. 공기청정기는 두 개의 인덱스를 차지하게 된다. 윗 부분에서는 반시계방향으로 회전하기 때문에 r의 인덱스가 0일 때, 윗 공기청정기 인덱스일 때, c의 인덱스가 0일 때, c-1일 때 공기청정기의 영향을 받는다.

아랫 부분에서는 시계방향으로 회전하면 r의 인덱스가 아랫 공기청정기 인덱스일때, r-1일때, 그리고 c의 인덱스가 0일 때, c-1일 때 영향을 받는다.

함수를 구성하고 나서 채점을 돌렸는데 Python에서는 시간초과가 발생하고, Pypy에서는 통과했다. 너무 비효율적으로 코드를 짠 것 같다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
def Spread():
    nextD=[[0 for i in range(c)]for j in range(r)]
    AirCleaner=[]
    for i in range(r):
        for j in range(c):
            if dusts[i][j]==-1:
                nextD[i][j]=-1
                AirCleaner.append(i)
            if dusts[i][j]>=1:
                count=0
                for k in range(4):
                    nx=i+dx[k]
                    ny=j+dy[k]
                    if 0<=nx<and 0<=ny<and dusts[nx][ny]!=-1:
                        count+=1
                        nextD[nx][ny]+=int(dusts[i][j]/5)
                nextD[i][j]+=dusts[i][j]-int(dusts[i][j]/5)*count
    return nextD,AirCleaner
 
def Clean(AC):
    nextD=[[0 for i in range(c)]for j in range(r)]
    for i in range(r):
        for j in range(c):
            if i<=AC[0]:
                if i==0:
                    if j==0:
                        nextD[i+1][j]=dusts[i][j]
                    else:
                        nextD[i][j-1]=dusts[i][j]
                    continue
                elif j==0:
                    if dusts[i][j]==-1:
                        pass
                    nextD[i+1][j]=dusts[i][j]
                elif j==c-1:
                    nextD[i-1][j]=dusts[i][j]
                    continue
                elif i==AC[0]:
                    if j==0:
                        pass
                    elif j==c-1:
                        nextD[i-1][j]=dusts[i][j]
                    else:
                        nextD[i][j+1]=dusts[i][j]
                    continue
                else:
                    nextD[i][j]=dusts[i][j]
            else:
                if i==AC[1]:
                    if j==0:
                        pass
                    elif j==c-1:
                        nextD[i+1][j]=dusts[i][j]
                    else:
                        nextD[i][j+1]=dusts[i][j]
                    continue
                elif j==0:
                    nextD[i-1][j]=dusts[i][j]
                    continue
                elif j==c-1:
                    if i==r-1:
                        nextD[i][j-1]=dusts[i][j]
                    else:
                        nextD[i+1][j]=dusts[i][j]
                    continue
                elif i==r-1:
                    if j==0:
                        nextD[i-1][j]=dusts[i][j]
                    else:
                        nextD[i][j-1]=dusts[i][j]
                    continue
                else:
                    nextD[i][j]=dusts[i][j]
                    continue
    nextD[AC[0]][0]=-1
    nextD[AC[1]][0]=-1
    return nextD
                       
r,c,t=map(int,input().split())
dusts=[]
for i in range(r):
    dusts.append(list(map(int,input().split())))
dx=[0,0,-1,1]
dy=[1,-1,0,0]
for i in range(t):
    dusts,AirCleaner=Spread()
    dusts=Clean(AirCleaner)
answer=0
for i in range(len(dusts)):
    answer+=sum(dusts[i])
print(answer+2)
cs

문제링크:

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

'Algorithm > Python' 카테고리의 다른 글

[BOJ]2960. 에라토스테네스의 체  (0) 2019.10.14
[BOJ]2851. 슈퍼 마리오  (0) 2019.10.13
[BOJ]1834. 나머지와 몫이 같은 수  (0) 2019.10.11
[BOJ]1357. 뒤집힌 덧셈  (0) 2019.10.08
[BOJ]1629. 곱셈  (0) 2019.10.07

문제:

오늘은 스타트링크에 다니는 사람들이 모여서 축구를 해보려고 한다. 축구는 평일 오후에 하고 의무 참석도 아니다. 축구를 하기 위해 모인 사람은 총 N명이고 신기하게도 N은 짝수이다. 이제 N/2명으로 이루어진 스타트팀과 링크 팀으로 사람들을 나눠야 한다.

 

BOJ를 운영하는 회사 답게 사람에게 번호를 1부터 N까지로 배정했고, 아래와 같은 능력치를 조사했다. 능력치 Sij는 i번 사람과 j번 사람이 같은 팀에 속했을 때, 팀에 더해지는 능력치이다. 팀의 능력치는 팀에 속한 모든 쌍의 능력치 Sij의 합이다. Sij는 Sji와 다를 수도 있으며, i번 사람과 j번 사람이 같은 팀에 속했을 때, 팀에 더해지는 능력치는 Sij와 Ski이다.

 

N=4이고, S가 아래와 같은 경우를 살펴보자.

예를 들어, 1,2번이 스타트 팀, 3, 4번이 링크 팀에 속한 경우에 두 팀의 능력치는 아래와 같다.

  •  스타트 팀: S12+S21 = 1+ 4 = 5
  •  링크 팀: S34 + S43 = 2 + 5 = 7

1,3 번이 스타팀, 2,4번이 링크 팀에 속하면, 두 팀의 능력치는 아래와 같다.

  •  스타트 팀: S13+S31 = 2+ 7 = 9
  •  링크 팀: S24 + S42 = 6 + 4 = 10

 축구를 재미있게 하기 위해서 스타트 팀의 능력치와 링크 팀의 능력치의 차이를 최소로 하려고 한다. 위의 예제와 같은 경우에는 1,4번이 스타트 팀, 2,3 번 팀이 링크 팀에 속하면 스타트 팀의 능력치는 6, 링크 팀의 능력치는 6의 되어서 차이가 0이 되고 이 값이 최소이다.

입력:

첫째 줄에 N(4<=N<=20, N은 짝수)이 주어진다. 둘째 줄부터 N개의 줄에 S가 주어진다. 각 줄은 N개의 수로 이루어져 있고, i번 줄의 j번째 수는 Sij 이다. Sii는 항상 0이고, 나머지 Sij는 1보다 크거나 같고, 100보다 작거나 같은 정수이다.

 

출력:

첫째 줄에 스타트 팀과 링크 팀의 능력치의 차이의 최솟값을 출력한다.

 

풀이 방법:

 N은 최대 20이므로 나올 수 있는 조합의 경우의 수는 20C10이다. 이 정도의 수를 반복하는 것은 충분히 가능하기 때문에 브루트포스로 풀어도 상관없을 것 같았다. 

 우선 python의 itertools를 사용해서 나올 수 있는 조합을 만들었다. 그리고 set을 사용해서 스타트팀과 링크 팀으로 구분을 했고, 스타트팀과 링크 팀을 이중 반복문을 통해서 시너지의 합을 구했다. 그리고 시너지간의 차를 배열에 담았다.위 작업을 모두 마치고 나서 배열의 min을 출력하도록 하였다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import itertools
import sys
n=int(sys.stdin.readline().strip())
temp=list(range(n))
synergy=[]
for i in range(n):
    synergy.append(list(map(int,sys.stdin.readline().strip().split())))
= list(itertools.combinations(temp,n//2))
answer=[]
for team in p:
    start = list(team)
    link = list(set(temp)-set(team))
    Synergy_start=0
    Synergy_link=0
    for i in start:
        for j in start:
            Synergy_start+=synergy[i][j]
    for i in link:
        for j in link:
            Synergy_link+=synergy[i][j]
    ans=abs(Synergy_link-Synergy_start)
    answer.append(ans)
print(min(answer))
cs

문제 링크:

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

'Algorithm > Python' 카테고리의 다른 글

[BOJ]1987. 알파벳  (0) 2019.09.25
[BOJ]1759. 암호 만들기  (0) 2019.09.24
[BOJ]1697. 숨바꼭질  (0) 2019.09.22
[BOJ]2022. 사다리  (0) 2019.09.21
[BOJ]1561. 놀이공원  (0) 2019.09.20

문제:

우리는 사람의 덩치를 키와 몸무게, 이 두 개의 값으로 표현하여 그 등수를 매겨보려고 한다. 어떤 사람의 몸무게가 x kg이고 키가 y cm라면 이 사람의 덩치는 (x,y)로 표시된다. 두 사람 A와 B의 덩치가 각각 (x,y) , (p,q)라고 할 때 x > p 그리고 y > q 이라면 우리는 A의 덩치가 B의 덩치보다 "더 크다"고 말한다. 예를 들어 어떤 A, B 두 사람의 덩치가 각각 (56,177), (45,165) 라고 한다면 A의 덩치가 B보다 큰 셈이 된다. 그런데 서로 다른 덩치끼리 크기를 정할 수 없는 경우도 있다. 예를 들어 두 사람 C와 D의 덩치가 각각 (45,181),(55,173)이라면 몸무게는 D가 C보다 더 무겁고, 키는 C가 더 크므로, "덩치"로만 볼 때 C와 D는 누구도 상대방보다 더 크다고 말할 수 없다.

이름 

<몸무게, 키> 

덩치 등수 

<55,185> 

B

<58,183>

C

<88,186> 

<60,175> 

<46,155> 


위 표에서 C보다 더 큰 덩치의 사람이 없으므로 C는 1등이 된다. 그리고 A, B, D 각각의 덩치보다 큰 사람은 C뿐이므로 이들은 모두 2등이 된다. 그리고 E보다 큰 덩치는 A,B,C,D 이렇게 4명이므로 E의 덩치는 5등이 된다. 위 경우에 3등과 4등은 존재한지 않는다. 여러분은 학생 N명의 몸무게와 키가 담긴 입력을 읽어서 각 사람의 덩치 등수를 계산하여 출력해야 한다.


입력:

첫 줄에는 전체 사람의 수 N이 주어진다. 그리고 이어지는 N개의 줄에는 각 사람의 몸무게와 키를 나타내는 양의 정수 x와 y가 하나의 공백을 두고 각각 나타난다. 단, 2<=N<=50, 10<=x,y<=200 이다.

출력:

여러분은 입력에 나열된 사람의 덩치 등수를 구해서 그 순서대로 첫 줄에 출력해야 한다. 단, 각 덩치 등수는 공백문자로 분리되어야 한다.

풀이 방법:

이중 for문을 사용해서 각 사람에 대해서 나머지 사람들 중 자신보다 덩치가 더 큰 사람 즉 키와 몸무게가 둘 다 많은 사람이 있을 경우 count를 추가해주면 된다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
bodys=[]
for i in range(int(input())):
    bodys.append(tuple(map(int,input().split())))
answer=[]
for i in range(len(bodys)):
    count=1
    for j in range(len(bodys)):
        if i==j:
            continue
        else:
            if bodys[i][0< bodys[j][0and bodys[i][1< bodys[j][1]:
                count+=1
    answer.append(count)
print(*answer)
cs


'Algorithm > Python' 카테고리의 다른 글

[BOJ]1002.터렛  (0) 2019.05.21
[BOJ]2293. 동전1  (0) 2019.05.20
[BOJ]2231. 분해합  (0) 2019.05.18
[BOJ]2309. 일곱 난쟁이  (0) 2019.05.17
[BOJ]1015. 수열 정렬  (0) 2019.05.16

문제:

어떤 자연수 N이 있을 때, 그 자연수  N의 분해합은 N과 N을 이루는 각 자리수의 합을 의미한다.
어떤 자연수 M의 분해합이 N인 경우, M을 N의 생성자라 한다. 예를 들어, 245의 분해합은 256(=245+2+4+5)이 된다. 따라서 245는 256의 생성자가 된다. 물론, 어떤 자연수의 경우에는 생성자가 없을 수도 있다. 반대로, 생성자가 여러 개인 자연수도 있을 수 있다.

자연수 N이 주어졌을 때, N의 가장 작은 생성자를 구해내는 프로그램을 작성하시오.

입력:

첫째 줄에 자연수 N(1<=N<=1,000,000)이 주어진다.

출력:

첫째 줄에 답을 출력한다. 생성자가 없는 경우에는 0을 출력한다.

풀이 방법:

브루트 포스로 풀어야 하는 문제이므로 count를 하나씩 증가시켜가며 분해합을 찾도록 한다. 생성자가 없는 경우 count가 answer보다 커지게 되므로 이 경우를 체크해줘야 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
answer=int(input())
 
count=1
while(True):
    temp=count
    for i in str(count): 
        temp+=int(i)
    if temp==answer:
        break
    elif count>answer:
        count=0
        break
    else:
        count+=1
print(count)
cs


'Algorithm > Python' 카테고리의 다른 글

[BOJ]2293. 동전1  (0) 2019.05.20
[BOJ]7568. 덩치  (0) 2019.05.19
[BOJ]2309. 일곱 난쟁이  (0) 2019.05.17
[BOJ]1015. 수열 정렬  (0) 2019.05.16
[BOJ]1547. 공  (0) 2019.05.15

문제:

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

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

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

입력:

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

출력:

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

풀이 방법:

브루트 포스 문제이므로 모든 나올 수 있는 경우의 수에 대해서 계산해주면 된다. 사실 경우의 수도 많은 편이 아니다.(9C7=9C2=36개)
파이썬에서 순열과 조합을 계산해줄 수 있도록 하는 모듈은 itertools를 사용했고, 그 중 combinations를 사용해서 9개 중 7개를 선택했다.
이 경우의 수 중 100이 되는 경우를 출력해주도록 한다.(답이 여러개라도 하나만 출력해도 괜찮으므로)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import itertools
 
Dwarfs=[]
for i in range(9):
    Dwarfs.append(int(input()))
Dwarfs.sort()
answers=list(itertools.combinations(Dwarfs,7))
for answer in answers:
    summation=0
    for i in answer:
        summation+=i
    if summation==100:
        temp=answer
        break
for i in temp:
    print(i)
cs


'Algorithm > Python' 카테고리의 다른 글

[BOJ]7568. 덩치  (0) 2019.05.19
[BOJ]2231. 분해합  (0) 2019.05.18
[BOJ]1015. 수열 정렬  (0) 2019.05.16
[BOJ]1547. 공  (0) 2019.05.15
[BOJ]10253. 헨리  (0) 2019.05.14

+ Recent posts