728x90
반응형

문제:

재귀 호출만 생각하면 신이 난다! 아닌가요?

다음과 같은 재귀함수 w(a, b, c)가 있다.

 

위의 함수를 구현하는 것은 매우 쉽다. 하지만, 그대로 구현하면 값을 구하는데 매우 오랜 시간이 걸린다. (예를 들면, a=15, b=15, c=15)

a, b, c가 주어졌을 때, w(a, b, c)를 출력하는 프로그램을 작성하시오.

입력:

입력은 세 정수 a, b, c로 이루어져 있으며, 한 줄에 하나씩 주어진다. 입력의 마지막은 -1 -1 -1로 나타내며, 세 정수가 모두 -1인 경우는 입력의 마지막을 제외하면 없다.

출력:

입력으로 주어진 각각의 a, b, c에 대해서, w(a, b, c)를 출력한다.

풀이방법:

그냥 이 함수를 재귀로 구성하면 시간초과가 발생하게 된다. 따라서 각 결과를 dp 테이블에 저장함으로써 시간을 단축시키도록 한다.

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
dp= [[[0 for _ in range(21)]for _ in range(21)]for _ in range(21)]
 
def w(a,b,c):
    if a<=0 or b<=0 or c<=0:
        return 1
    if a > 20 or b > 20 or c >20:
        return w(20,20,20)
    temp = dp[a][b][c]
    if temp!=0:
        return temp
    if a < b and b < c:
        ans = w(a,b,c-1)+w(a,b-1,c-1)-w(a,b-1,c)
        dp[a][b][c]=ans
        return ans
    else:
        ans = w(a-1,b,c)+w(a-1,b-1,c)+w(a-1,b,c-1)-w(a-1,b-1,c-1)
        dp[a][b][c]=ans
        return ans
 
while True:
    a,b,c=map(int,input().split())
    if a==-1 and b==-1 and c==-1:
        break
    else:
        print("w({}, {}, {}) =".format(a,b,c),w(a,b,c))
cs

문제링크:

www.acmicpc.net/problem/9184

 

9184번: 신나는 함수 실행

입력은 세 정수 a, b, c로 이루어져 있으며, 한 줄에 하나씩 주어진다. 입력의 마지막은 -1 -1 -1로 나타내며, 세 정수가 모두 -1인 경우는 입력의 마지막을 제외하면 없다.

www.acmicpc.net

 

728x90
반응형

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

[BOJ]2630. 색종이 만들기  (0) 2021.04.29
[BOJ]3273. 두 수의 합  (0) 2021.04.27
[BOJ]2981. 검문  (0) 2021.04.20
[BOJ]10819. 차이를 최대로  (0) 2021.02.25
[BOJ]14888. 연산자 끼워넣기  (0) 2021.02.23
728x90
반응형

문제:

트럭을 타고 이동하던 상근이는 경찰의 검문을 받게 되었다. 경찰은 상근이가 운반하던 화물을 하나하나 모두 확인할 것이기 때문에, 검문하는데 엄청나게 오랜 시간이 걸린다.

상근이는 시간을 때우기 위해서 수학 게임을 하기로 했다.

먼저 근처에 보이는 숫자 N개를 종이에 적는다. 그 다음, 종이에 적은 수를 M으로 나누었을 때, 나머지가 모두 같게 되는 M을 모두 찾으려고 한다. M은 1보다 커야 한다.

N개의 수가 주어졌을 때, 가능한 M을 모두 찾는 프로그램을 작성하시오.

입력:

첫째 줄에 종이에 적은 수의 개수 N이 주어진다. (2 ≤ N ≤ 100)

다음 줄부터 N개 줄에는 종이에 적은 수가 하나씩 주어진다. 이 수는 모두 1보다 크거나 같고, 1,000,000,000보다 작거나 같은 자연수이다. 같은 수가 두 번 이상 주어지지 않는다.

항상 M이 하나 이상 존재하는 경우만 입력으로 주어진다.

출력:

첫째 줄에 가능한 M을 공백으로 구분하여 모두 출력한다. 이때, M은 증가하는 순서이어야 한다.

풀이방법:

 N개의 숫자들을 M으로 나눴을 때 나머지가 모두 같은 M을 찾기 위해서는 N개의 숫자들을 큰 순서로 정렬한 뒤에 그들의 차를 구하고 GCD를 계산하면 된다. 이 것이 가능한 이유는 간략히 설명하면 다음과 같다. 

 

 숫자 A, B가 있고 M으로 나누면 나머지가 R로 같다고 하자. 그러면 다음과 같이 식으로 쓸 수 있다.

 

A = a*M + R

B = b*M + R

 

이들의 차를 구하면 다음과 같이 된다.

 

A-B = (a-b)*M

 

따라서 M은 A와 B의 GCD를 의미하게 되고 가능한 M은 해당 GCD들의 약수일 것이다.

 

python의 math.gcd를 사용하고, 이 값에 대해 약수를 구하는 함수를 구해 M을 출력하도록 한다.

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
from math import gcd,sqrt
 
def divisor(n):
    divList = {n}
    for i in range(2,int(sqrt(n)+1)):
        if n%i==0:
            divList.add(i)
            divList.add(n//i)
    divList = sorted(list(divList))
    return divList
    
 
= int(input())
numbers=[]
for _ in range(n):
    numbers.append(int(input()))
numbers.sort(reverse=True)    
 
diff = []
for i in range(len(numbers)-1):
    diff.append(numbers[i]-numbers[i-1])
    
answer = diff[0]
for i in range(1,len(diff)):
    answer = gcd(answer,diff[i])
 
print(*divisor(answer))
cs

문제링크:

www.acmicpc.net/problem/2981

728x90
반응형

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

[BOJ]3273. 두 수의 합  (0) 2021.04.27
[BOJ]9184. 신나는 함수 실행  (0) 2021.04.22
[BOJ]10819. 차이를 최대로  (0) 2021.02.25
[BOJ]14888. 연산자 끼워넣기  (0) 2021.02.23
[BOJ]2885. 초콜릿 식사  (0) 2021.02.16
728x90
반응형

문제:

N개의 정수로 이루어진 배열 A가 주어진다. 이때, 배열에 들어있는 정수의 순서를 적절히 바꿔서 다음 식의 최댓값을 구하는 프로그램을 작성하시오.

|A[0] - A[1]| + |A[1] - A[2]| + ... + |A[N-2] - A[N-1]|

입력:

첫째 줄에 N (3 ≤ N ≤ 8)이 주어진다. 둘째 줄에는 배열 A에 들어있는 정수가 주어진다. 배열에 들어있는 정수는 -100보다 크거나 같고, 100보다 작거나 같다.

출력:

첫째 줄에 배열에 들어있는 수의 순서를 적절히 바꿔서 얻을 수 있는 식의 최댓값을 출력한다.

풀이방법:

 뭔가 그리디한 방법을 사용해서도 풀 수 있는 방법이 있을 것 같지만, 경우의 수가 적으므로 이 문제 역시 permutation을 사용해서 모든 경우의 수를 만들어줌으로써 풀었다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import itertools
 
= int(input())
numbers = list(map(int,input().split()))
 
candidates = list(itertools.permutations(numbers,n))
answer = 0
for can in candidates:
    temp = 0
    for i in range(n-1):
        temp += abs(can[i]-can[i+1])
    if answer < temp:
        answer = temp
print(answer)
cs

문제링크:

www.acmicpc.net/problem/10819

 

10819번: 차이를 최대로

첫째 줄에 N (3 ≤ N ≤ 8)이 주어진다. 둘째 줄에는 배열 A에 들어있는 정수가 주어진다. 배열에 들어있는 정수는 -100보다 크거나 같고, 100보다 작거나 같다.

www.acmicpc.net

 

728x90
반응형

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

[BOJ]9184. 신나는 함수 실행  (0) 2021.04.22
[BOJ]2981. 검문  (0) 2021.04.20
[BOJ]14888. 연산자 끼워넣기  (0) 2021.02.23
[BOJ]2885. 초콜릿 식사  (0) 2021.02.16
[BOJ]2621. 카드게임  (0) 2021.02.09
728x90
반응형

문제:

N개의 수로 이루어진 수열 A1, A2, ..., AN이 주어진다. 또, 수와 수 사이에 끼워넣을 수 있는 N-1개의 연산자가 주어진다. 연산자는 덧셈(+), 뺄셈(-), 곱셈(×), 나눗셈(÷)으로만 이루어져 있다.

우리는 수와 수 사이에 연산자를 하나씩 넣어서, 수식을 하나 만들 수 있다. 이때, 주어진 수의 순서를 바꾸면 안 된다.

예를 들어, 6개의 수로 이루어진 수열이 1, 2, 3, 4, 5, 6이고, 주어진 연산자가 덧셈(+) 2개, 뺄셈(-) 1개, 곱셈(×) 1개, 나눗셈(÷) 1개인 경우에는 총 60가지의 식을 만들 수 있다. 예를 들어, 아래와 같은 식을 만들 수 있다.

  • 1+2+3-4×5÷6
  • 1÷2+3+4-5×6
  • 1+2÷3×4-5+6
  • 1÷2×3-4+5+6

식의 계산은 연산자 우선 순위를 무시하고 앞에서부터 진행해야 한다. 또, 나눗셈은 정수 나눗셈으로 몫만 취한다. 음수를 양수로 나눌 때는 C++14의 기준을 따른다. 즉, 양수로 바꾼 뒤 몫을 취하고, 그 몫을 음수로 바꾼 것과 같다. 이에 따라서, 위의 식 4개의 결과를 계산해보면 아래와 같다.

  • 1+2+3-4×5÷6 = 1
  • 1÷2+3+4-5×6 = 12
  • 1+2÷3×4-5+6 = 5
  • 1÷2×3-4+5+6 = 7

N개의 수와 N-1개의 연산자가 주어졌을 때, 만들 수 있는 식의 결과가 최대인 것과 최소인 것을 구하는 프로그램을 작성하시오.

입력:

첫째 줄에 수의 개수 N(2 ≤ N ≤ 11)가 주어진다. 둘째 줄에는 A1, A2, ..., AN이 주어진다. (1 ≤ Ai ≤ 100) 셋째 줄에는 합이 N-1인 4개의 정수가 주어지는데, 차례대로 덧셈(+)의 개수, 뺄셈(-)의 개수, 곱셈(×)의 개수, 나눗셈(÷)의 개수이다. 

출력:

첫째 줄에 만들 수 있는 식의 결과의 최댓값을, 둘째 줄에는 최솟값을 출력한다. 연산자를 어떻게 끼워넣어도 항상 -10억보다 크거나 같고, 10억보다 작거나 같은 결과가 나오는 입력만 주어진다. 또한, 앞에서부터 계산했을 때, 중간에 계산되는 식의 결과도 항상 -10억보다 크거나 같고, 10억보다 작거나 같다.

풀이방법:

***pypy3으로 통과한 문제입니다.***

 브루트포스 알고리즘을 이용하기 위해 itertools의 permutation을 사용해서 모든 경우의 수를 만들어준다. 만들어진 경우의 수에 따라 조건문으로 알맞게 계산하면 된다. 단, 음수에 대한 나눗셈은 정해진 기준에 맞게 계산되도록 해준다.

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
import sys
 
input = sys.stdin.readline
 
= int(input())
numbers = list(map(int,input().split()))
op = list(map(int,input().split()))
temp = []
 
for i in range(0,4):
    for j in range(0,op[i]):
        temp.append(str(i))
        
import itertools
 
candidates = list(itertools.permutations(temp,n-1))
 
maxAns = -float('inf')
minAns = float('inf')
for can in candidates:
    res = numbers[0]
    for i,v in enumerate(can):
        if v=='0':
            res+=numbers[i+1]
        elif v=='1':
            res-=numbers[i+1]
        elif v=='2':
            res*=numbers[i+1]
        elif v=='3':
            if res < 0:
                res = -(abs(res)//numbers[i+1])
            else:
                res//=numbers[i+1]
    if maxAns < res:
        maxAns = res
    if minAns > res:
        minAns = res
        
print(maxAns)
print(minAns)
cs

문제링크:

www.acmicpc.net/problem/14888

 

14888번: 연산자 끼워넣기

첫째 줄에 수의 개수 N(2 ≤ N ≤ 11)가 주어진다. 둘째 줄에는 A1, A2, ..., AN이 주어진다. (1 ≤ Ai ≤ 100) 셋째 줄에는 합이 N-1인 4개의 정수가 주어지는데, 차례대로 덧셈(+)의 개수, 뺄셈(-)의 개수, 

www.acmicpc.net

 

728x90
반응형

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

[BOJ]2981. 검문  (0) 2021.04.20
[BOJ]10819. 차이를 최대로  (0) 2021.02.25
[BOJ]2885. 초콜릿 식사  (0) 2021.02.16
[BOJ]2621. 카드게임  (0) 2021.02.09
[BOJ]2061. 좋은 암호  (0) 2021.02.04
728x90
반응형

문제:

학교 근처 편의점에 새 초콜릿이 들어왔다. 이 초콜릿은 막대 모양이고, 각 막대는 정사각형 N개로 이루어져 있다. 초콜릿의 크기(정사각형의 개수)는 항상 2의 제곱 형태이다. 즉, 1, 2, 4, 8, 16, ...개의 정사각형으로 이루어져 있다.

상근이는 점심식사로 초콜릿을 먹는다. 이때, 적어도 K개 정사각형을 먹어야 남은 수업을 졸지 않고 버틸 수 있다. 상근이의 친구 선영이도 초콜릿을 좋아한다. 선영이는 초콜릿은 돈을 주고 사기 아깝다고 생각하기 때문에, 상근이가 주는 초콜릿만 먹는다.

상근이는 막대 초콜릿를 하나 산 다음에, 정확하게 K개 정사각형이 되도록 초콜릿을 쪼갠다. K개는 자신이 먹고 남는 것은 선영이에게 준다.

막대 초콜릿은 나누기 조금 어렵게 되어 있어서, 항상 가운데로만 쪼개진다. 즉, 정사각형이 D개 있는 막대는 D/2개 막대 두 조각으로 쪼개진다.

K개 정사각형을 만들기 위해서, 최소 몇 번 초콜릿을 쪼개야 하는지와 사야하는 가장 작은 초콜릿의 크기를 구하는 프로그램을 작성하시오. 상근이는 초콜릿을 하나만 살 수 있다. 꼭 한 조각이 K개일 필요는 없고, 여러 조각에 있는 정사각형을 합쳤을 때 K개이면 된다.

입력:

첫째 줄에 K가 주어진다. (1 ≤ K ≤ 1,000,000)

출력:

첫째 줄에는 상근이가 구매해야하는 가장 작은 초콜릿의 크기와 최소 몇 번 쪼개야 하는지를 출력한다.

풀이방법:

그리디한 방법을 사용해서 풀어야 하는 문제다.

1부터 2배씩 곱해나가면서 사야하는 가장 작은 초콜릿을 구매를 한 후, 그 초콜릿으로 부터 반으로 쪼개면서 답을 구한다.

반으로 쪼갠 후에 원하는 초콜릿 크기보다 작다면 그 크기만큼 빼주고 count를 하나 늘리고, 아직 크다면 다시 반으로 쪼개는 작업을 반복한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
n=int(input())
size = 1
max_len = 0
answer = 0
 
while size < n:
    size *=2
    max_len = size
 
while n>0:
    if n>=size:
        n-=size
    else:
        size/=2
        answer+=1
 
print(max_len,answer)
cs

문제링크:

www.acmicpc.net/problem/2885

 

2885번: 초콜릿 식사

학교 근처 편의점에 새 초콜릿이 들어왔다. 이 초콜릿은 막대 모양이고, 각 막대는 정사각형 N개로 이루어져 있다. 초콜릿의 크기(정사각형의 개수)는 항상 2의 제곱 형태이다. 즉, 1, 2, 4, 8, 16, ...

www.acmicpc.net

 

728x90
반응형

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

[BOJ]10819. 차이를 최대로  (0) 2021.02.25
[BOJ]14888. 연산자 끼워넣기  (0) 2021.02.23
[BOJ]2621. 카드게임  (0) 2021.02.09
[BOJ]2061. 좋은 암호  (0) 2021.02.04
[BOJ]1251. 단어 나누기  (0) 2021.02.02
728x90
반응형

문제:

근우는 오늘 재미있는 카드 게임을 배우고 있다. 카드는 빨간색, 파란색, 노란색, 녹색의 네 가지 색이 있고, 색깔별로 1부터 9까지 숫자가 쓰여진 카드가 9장씩 있다. 카드는 모두 36(=4x9)장이다. 근우가 배운 카드 게임은 36장의 카드에서 5장을 뽑고, 아래와 같은 규칙으로 정수를 계산하는 것이다.

각 카드는 다음과 같이 나타낸다. 카드의 색깔은 영어 대문자 R, B, Y, G로 나타내는데, R은 빨간색, B는 파란색, Y는 노란색, G는 녹색을 뜻한다. 예를 들어서 Y8은 노란색 8을 나타내고, B5는 파란색 5를 나타낸다.

 

<점수를 정하는 규칙>

  1. 카드 5장이 모두 같은 색이면서 숫자가 연속적일 때, 점수는 가장 높은 숫자에 900을 더한다. 예를 들어, 카드가 Y4, Y3, Y2, Y5, Y6 일 때 점수는 906(=6+900)점이다.
  2. 카드 5장 중 4장의 숫자가 같을 때 점수는 같은 숫자에 800을 더한다. 예를 들어, 카드가 B3, R3, B7, Y3, G3 일 때 점수는 803(=3+800)점이다.
  3. 카드 5장 중 3장의 숫자가 같고 나머지 2장도 숫자가 같을 때 점수는 3장이 같은 숫자에 10을 곱하고 2장이 같은 숫자를 더한 다음 700을 더한다. 예를 들어, 카드가 R5, Y5, G7, B5, Y7 일 때 점수는 757(=5x10+7+700)점이다.
  4. 5장의 카드 색깔이 모두 같을 때 점수는 가장 높은 숫자에 600을 더한다. 예를 들어, 카드가 Y3, Y4, Y8, Y6, Y7 일 때 점수는 608(=8+600)점이다.
  5. 카드 5장의 숫자가 연속적일 때 점수는 가장 높은 숫자에 500을 더한다. 예를 들어 R7, R8, G9, Y6, B5 일 때 점수는 509(=9+500)점이다.
  6. 카드 5장 중 3장의 숫자가 같을 때 점수는 같은 숫자에 400을 더한다. 예를 들어 R7, Y7, R2, G7, R5 일 때 점수는 407(=7+400)점이다.
  7. 카드 5장 중 2장의 숫자가 같고 또 다른 2장의 숫자가 같을 때 점수는 같은 숫자 중 큰 숫자에 10을 곱하고 같은 숫자 중 작은 숫자를 더한 다음 300을 더한다. 예를 들어, R5, Y5, Y4, G9, B4 일 때 점수는 354(=5X10+4+300)점이다.
  8. 카드 5장 중 2장의 숫자가 같을 때 점수는 같은 숫자에 200을 더한다. 예를 들어, R5, Y2, B5, B3, G4 일 때 점수는 205(=5+200)점이다.
  9. 위의 어떤 경우에도 해당하지 않을 때 점수는 가장 큰 숫자에 100을 더한다. 예를 들어, R1, R2, B4, B8, Y5 일 때 점수는 108(=8+100)점이다.

입력으로 카드 5장이 주어질 때, 카드 게임의 점수를 구하는 프로그램을 작성하시오. 두 가지 이상의 규칙을 적용할 수 있는 경우에는 가장 높은 점수가 카드 게임의 점수이다.

입력:

첫째 줄부터 다섯째 줄까지 한 줄에 카드 하나씩 입력된다. 카드의 색깔과 숫자 사이에는 빈 칸이 하나 있다.

출력:

한 줄에 카드의 점수를 출력한다.

풀이방법:

 주어진 규칙에 알맞게 점수계산을 하면 된다. 규칙 조건에 따라 중복으로 계산이 되는 경우가 존재하는데 조건문을 통해 최댓값을 가지도록 한다.

규칙을 크게 보면 다음과 같이 세 가지가 있다.

 

<색 조건>

1. 모두 같은 색을 가지는 가?

<숫자 조건>

2. 숫자가 연속 되는가?

3. 공통된 숫자가 K개 있다.

 

따라서 각 조건에 대해 다음과 같은 방법을 사용한다.

 

1. set 연산을 사용해 원소의 갯수가 1이면 모두 같은 색이다.

2. 가장 큰 값과 가장 작은 값의 차이가 4면 연속되어 있다.

3. 숫자가 key, 갯수가 value은 dict 자료형을 사용한다.

 

위 방법들 사용해서 해당하는 규칙을 찾고 그에 맞게 계산하면 된다.

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
color = [];number = {}
for _ in range(5):
    c, n = input().split()
    color.append(c)
    if number.get(int(n)):
        number[int(n)]+=1
    else:
        number[int(n)]=1
 
answer = 0
key = number.keys()
value = sorted(number.values())
if len(set(color))==1 and max(key)-min(key)==4:
    temp = 900+max(key)
    if temp >  answer:
        answer = temp
elif value[-1]==4:
    for k,v in number.items():
        if v==4:
            temp = 800+k
            break
    if temp >  answer:
        answer = temp
elif value == [2,3]:
    temp = 700
    for k,v in number.items():
        if v==2:
            temp+=k
        elif v==3:
            temp+=k*10
    if temp >  answer:
        answer = temp
elif len(set(color))==1:
    temp = 600+max(key)
    if temp >  answer:
        answer = temp
elif max(key)-min(key)==4:
    temp = 500+max(key)
    if temp > answer:
        answer = temp
elif value[-1]==3:
    temp = 400
    for k,v in number.items():
        if v==3:
            temp+=k
    if temp > answer:
        answer = temp
elif value == [1,2,2]:
    temp = 300+sorted(number.items(),key = lambda x: x[1])[1][0]*10+sorted(number.items(),key = lambda x: x[1])[2][0]
    if temp > answer:
        answer = temp
elif value[-1]==2:
    temp = 200+sorted(number.items(),key = lambda x: x[1])[-1][0]
    if temp > answer:
        answer = temp
else:
    temp = 100+max(key)
    if temp > answer:
        answer = temp
print(answer)
cs

문제링크:

www.acmicpc.net/problem/2621

 

2621번: 카드게임

근우는 오늘 재미있는 카드 게임을 배우고 있다. 카드는 빨간색, 파란색, 노란색, 녹색의 네 가지 색이 있고, 색깔별로 1부터 9까지 숫자가 쓰여진 카드가 9장씩 있다. 카드는 모두 36(=4x9)장이다.

www.acmicpc.net

 

728x90
반응형

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

[BOJ]14888. 연산자 끼워넣기  (0) 2021.02.23
[BOJ]2885. 초콜릿 식사  (0) 2021.02.16
[BOJ]2061. 좋은 암호  (0) 2021.02.04
[BOJ]1251. 단어 나누기  (0) 2021.02.02
[BOJ]1715. 카드 정렬하기  (0) 2021.01.28
728x90
반응형

문제:

암호화 방식 중에는 소수를 이용하는 것들이 많다. 보통은 매우 큰 두 개의 소수를 선택하고, 두 소수를 곱한 값을 암호화에서의 키로 사용하고는 한다. 이러한 방법이 좋은 이유는 일반적으로 매우 큰 수를 소인수분해 하는 것이 어렵기 때문이다.

소수를 택할 때 큰 수를 택하면, 이 둘을 곱해서 얻어지는 키 값도 커지게 된다. 하지만 그 반대는 성립하지 않을 수도 있다. 즉, 키 값이 매우 큰 경우에도 이를 소인수분해 하는 것은 쉬울 수도 있다.

따라서 암호문이 크랙되지 않도록 하기 위해서는, 키 값이 적절히 큰 수들의 곱으로 이루어져 있는지를 확인해야 할 필요가 있다. 키 값 K(4≤K≤10^100)와 정수 L(2≤L≤1,000,000)이 주어졌을 때, K를 인수분해 했을 때, 항상 L 이상의 값으로만 이루어져 있는지를 확인하고 싶다. 물론 인수분해 할 때 1로 나누는 경우는 고려하지 않는다.

예를 들어 K=143인 경우, 이는 11과 13의 곱으로 이루어져 있다. 즉, 이를 인수분해 하는 방법은 11×13, 143의 두 가지 경우뿐이다. 따라서 L이 11일 경우에는 인수분해 했을 때 나온 수들이 모두 L 이상이므로 좋은 경우지만, L이 12이상일 경우에는 좋은 암호가 아니다.

K와 L이 주어졌을 때, 좋은 암호인지 판단하는 프로그램을 작성하시오.

입력:

첫째 줄에 두 정수 K, L이 주어진다.

출력:

좋은 암호인 경우에는 GOOD을 출력한다. 나쁜 암호일 경우에는 BAD를 출력하고, K의 가장 작은 (1 아닌) 인수를 출력한다.

풀이방법:

K가 L 미만의 소수로 나눠지는지 확인하면 되는 문제다. 따라서 에라토스테네스의 체를 사용해서 L 미만의 소수를 찾은 뒤에 그 소수들로 K로 나눠본다.

나눠지면 BAD와 함께 그 수를 출력하고, 나눠지지 않는다면 GOOD을 출력하도록 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import sys
K, L = map(int,input().split())
 
candidate = []
sosu = [True]*L
sosu[0]=False;sosu[1]=False
for i in range(2,L):
    if sosu[i]:
        candidate.append(i)
        for j in range(i,L,i):
            sosu[j]=False
            
for can in candidate:
    if K%can==0:
        print("BAD",can)
        sys.exit()
print("GOOD")
cs

문제링크:

www.acmicpc.net/problem/2061

 

2061번: 좋은 암호

암호화 방식 중에는 소수를 이용하는 것들이 많다. 보통은 매우 큰 두 개의 소수를 선택하고, 두 소수를 곱한 값을 암호화에서의 키로 사용하고는 한다. 이러한 방법이 좋은 이유는 일반적으로

www.acmicpc.net

 

728x90
반응형

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

[BOJ]2885. 초콜릿 식사  (0) 2021.02.16
[BOJ]2621. 카드게임  (0) 2021.02.09
[BOJ]1251. 단어 나누기  (0) 2021.02.02
[BOJ]1715. 카드 정렬하기  (0) 2021.01.28
[BOJ]2529. 부등호  (0) 2021.01.26
728x90
반응형

문제:

알파벳 소문자로 이루어진 단어를 가지고 아래와 같은 과정을 해 보려고 한다.

먼저 단어에서 임의의 두 부분을 골라서 단어를 쪼갠다. 즉, 주어진 단어를 세 개의 더 작은 단어로 나누는 것이다. 각각은 적어도 길이가 1 이상인 단어여야 한다. 이제 이렇게 나눈 세 개의 작은 단어들을 앞뒤를 뒤집고, 이를 다시 원래의 순서대로 합친다.

예를 들어,

  • 단어 : arrested
  • 세 단어로 나누기 : ar / rest / ed
  • 각각 뒤집기 : ra / tser / de
  • 합치기 : ratserde

단어가 주어지면, 이렇게 만들 수 있는 단어 중에서 사전순으로 가장 앞서는 단어를 출력하는 프로그램을 작성하시오.

입력:

첫째 줄에 영어 소문자로 된 단어가 주어진다. 길이는 3 이상 50 이하이다.

출력:

첫째 줄에 구하고자 하는 단어를 출력하면 된다.

풀이방법:

반복문 두 개를 사용해서 주어진 조건대로 하나씩 단어를 만들면서 해당하는 단어가 사전상 먼저 인지 확인하면 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
string = input()
answer = 'z'*16
for i in range(1,len(string)-1):
    for j in range(i+1,len(string)):
        temp = ''
        for t in range(len(string[:i])-1,-1,-1):
            temp+=string[:i][t]
        for t in range(len(string[i:j])-1,-1,-1):
            temp+=string[i:j][t]
        for t in range(len(string[j:])-1,-1,-1):
            temp+=string[j:][t]
        if answer > temp:
            answer = temp
print(answer)
cs

문제링크:

www.acmicpc.net/problem/1251

 

1251번: 단어 나누기

알파벳 소문자로 이루어진 단어를 가지고 아래와 같은 과정을 해 보려고 한다. 먼저 단어에서 임의의 두 부분을 골라서 단어를 쪼갠다. 즉, 주어진 단어를 세 개의 더 작은 단어로 나누는 것이다

www.acmicpc.net

 

728x90
반응형

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

[BOJ]2621. 카드게임  (0) 2021.02.09
[BOJ]2061. 좋은 암호  (0) 2021.02.04
[BOJ]1715. 카드 정렬하기  (0) 2021.01.28
[BOJ]2529. 부등호  (0) 2021.01.26
[BOJ]2003. 수들의 합 2  (0) 2021.01.19
728x90
반응형

문제:

정렬된 두 묶음의 숫자 카드가 있다고 하자. 각 묶음의 카드의 수를 A, B라 하면 보통 두 묶음을 합쳐서 하나로 만드는 데에는 A+B 번의 비교를 해야 한다. 이를테면, 20장의 숫자 카드 묶음과 30장의 숫자 카드 묶음을 합치려면 50번의 비교가 필요하다.

매우 많은 숫자 카드 묶음이 책상 위에 놓여 있다. 이들을 두 묶음씩 골라 서로 합쳐나간다면, 고르는 순서에 따라서 비교 횟수가 매우 달라진다. 예를 들어 10장, 20장, 40장의 묶음이 있다면 10장과 20장을 합친 뒤, 합친 30장 묶음과 40장을 합친다면 (10 + 20) + (30 + 40) = 100번의 비교가 필요하다. 그러나 10장과 40장을 합친 뒤, 합친 50장 묶음과 20장을 합친다면 (10 + 40) + (50 + 20) = 120 번의 비교가 필요하므로 덜 효율적인 방법이다.

N개의 숫자 카드 묶음의 각각의 크기가 주어질 때, 최소한 몇 번의 비교가 필요한지를 구하는 프로그램을 작성하시오.

입력:

첫째 줄에 N이 주어진다. (1 ≤ N ≤ 100,000) 이어서 N개의 줄에 걸쳐 숫자 카드 묶음의 각각의 크기가 주어진다. 숫자 카드 묶음의 크기는 1,000보다 작거나 같은 양의 정수이다.

출력:

첫째 줄에 최소 비교 횟수를 출력한다.

풀이방법:

최소한의 비교를 하기 위해서는 계속해서 가장 작은 두 수를 골라서 비교를 하는 것이 이득이다. 따라서 python의 heapq를 사용해 최소힙을 구성한다.

heappop을 사용해서 가장 작은 두 값을 뽑아내고, 이 둘을 합친 값을 다시 heap에 넣는다. 이를 heap에 하나의 원소가 남을 때까지 반복하면 최소 비교 횟수를 얻을 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import heapq
= []
= int(input())
for _ in range(n):
    heapq.heappush(h,int(input()))
 
answer = 0
while len(h)>=2:
    one = heapq.heappop(h)
    two = heapq.heappop(h)
    temp = one+two
    answer+=temp
    heapq.heappush(h,temp)
 
print(answer)
cs

문제링크:

www.acmicpc.net/problem/1715

 

1715번: 카드 정렬하기

정렬된 두 묶음의 숫자 카드가 있다고 하자. 각 묶음의 카드의 수를 A, B라 하면 보통 두 묶음을 합쳐서 하나로 만드는 데에는 A+B 번의 비교를 해야 한다. 이를테면, 20장의 숫자 카드 묶음과 30장

www.acmicpc.net

 

728x90
반응형

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

[BOJ]2061. 좋은 암호  (0) 2021.02.04
[BOJ]1251. 단어 나누기  (0) 2021.02.02
[BOJ]2529. 부등호  (0) 2021.01.26
[BOJ]2003. 수들의 합 2  (0) 2021.01.19
[BOJ]2661. 좋은 수열  (0) 2021.01.14
728x90
반응형

문제:

두 종류의 부등호 기호 ‘<’와 ‘>’가 k개 나열된 순서열  A가 있다. 우리는 이 부등호 기호 앞뒤에 서로 다른 한 자릿수 숫자를 넣어서 모든 부등호 관계를 만족시키려고 한다. 예를 들어, 제시된 부등호 순서열 A가 다음과 같다고 하자.

A =>  < < < > < < > < >

부등호 기호 앞뒤에 넣을 수 있는 숫자는 0부터 9까지의 정수이며 선택된 숫자는 모두 달라야 한다. 아래는 부등호 순서열 A를 만족시키는 한 예이다. 

3 < 4 < 5 < 6 > 1 < 2 < 8 > 7 < 9 > 0

이 상황에서 부등호 기호를 제거한 뒤, 숫자를 모두 붙이면 하나의 수를 만들 수 있는데 이 수를 주어진 부등호 관계를 만족시키는 정수라고 한다. 그런데 주어진 부등호 관계를 만족하는 정수는 하나 이상 존재한다. 예를 들어 3456128790 뿐만 아니라 5689023174도 아래와 같이 부등호 관계 A를 만족시킨다. 

5 < 6 < 8 < 9 > 0 < 2 < 3 > 1 < 7 > 4

여러분은 제시된 k개의 부등호 순서를 만족하는 (k+1)자리의 정수 중에서 최댓값과 최솟값을 찾아야 한다. 앞서 설명한 대로 각 부등호의 앞뒤에 들어가는 숫자는 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }중에서 선택해야 하며 선택된 숫자는 모두 달라야 한다

입력:

첫 줄에 부등호 문자의 개수를 나타내는 정수 k가 주어진다. 그 다음 줄에는 k개의 부등호 기호가 하나의 공백을 두고 한 줄에 모두 제시된다. k의 범위는 2 ≤ k ≤ 9 이다. 

출력:

여러분은 제시된 부등호 관계를 만족하는 k+1 자리의 최대, 최소 정수를 첫째 줄과 둘째 줄에 각각 출력해야 한다. 단 아래 예(1)과 같이 첫 자리가 0인 경우도 정수에 포함되어야 한다. 모든 입력에 답은 항상 존재하며 출력 정수는 하나의 문자열이 되도록 해야 한다. 

풀이방법:

 처음에는 itertools의 permutation을 사용해서 풀려고 했으나, 메모리 초과가 발생했다. 아무래도 경우의 수가 엄청 많기 때문에 발생한 것 같았다.

 따라서 백트래킹(dfs)를 사용해서 효율적으로 구하려고 했다. visited 배열을 만들어서 사용한 숫자, 그렇지 않은 숫자를 구분했고, 빈 문자열로 시작했기 때문에 length==0이라는 조건을 넣어주게 되었다. is_possible 함수를 통해 부등호를 만족하는 조건의 숫자들을 구했으면 이를 answer 배열에 넣도록 한다. 

 이 때, answer 배열들의 숫자들은 작은 숫자부터 생성하기 시작했기 때문에 맨 처음에는 "부등호를 만족하는 가장 작은 숫자", 맨 마지막에는 "부등호를 만족하는 가장 큰 숫자"가 들어가 있게 된다. 따라서 이를 알맞게 출력하면 된다.

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
def is_possible(i,op,j):
    if op == ">":
        return i > j
    else:
        return i < j
 
def dfs(length,can):
    global answer
    if length==n+1:
        answer.append(can)
        return
    for i in range(10):
        if not visited[i]:
            if length==0 or is_possible(can[-1],ie[length-1],str(i)):
                visited[i] = True
                dfs(length+1,can+str(i))
                visited[i] = False
                
n=int(input())
ie = input().split()
numbers  = list(range(10))
visited = [False]*10
answer = []
dfs(0,"")
print(answer[-1])
print(answer[0])
cs

문제링크:

www.acmicpc.net/problem/2529

 

2529번: 부등호

두 종류의 부등호 기호 ‘<’와 ‘>’가 k개 나열된 순서열  A가 있다. 우리는 이 부등호 기호 앞뒤에 서로 다른 한 자릿수 숫자를 넣어서 모든 부등호 관계를 만족시키려고 한다. 예를 들어, 제

www.acmicpc.net

 

728x90
반응형

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

[BOJ]1251. 단어 나누기  (0) 2021.02.02
[BOJ]1715. 카드 정렬하기  (0) 2021.01.28
[BOJ]2003. 수들의 합 2  (0) 2021.01.19
[BOJ]2661. 좋은 수열  (0) 2021.01.14
[BOJ]15711. 환상의 짝꿍  (0) 2021.01.12

+ Recent posts