728x90
반응형

문제:

어떤 동물원에 가로로 두 칸 세로로 N칸인 아래와 같은 우리가 있다.

 

[출처]https://www.acmicpc.net/problem/1309

이 동물원에는 사자들이 살고 있는데 사자들을 우리에 가둘 때, 가로로도 세로로도 불어 있게 배치할 수는 없다.

이 동물원 조련사는 사자들의 배치 문제 때문에 골머리를 앓고 있다.

 

동물원 조련사의 머리가 아프지 않도록 우리가 2*N 배열에 사자를 배치하는 경우의 수가 몇 가지인지를 알아내는 프로그램을 작성해 주도록 하자. 사자를 한 마리도 배치하지 않는 경우도 하나의 경우의 수로 친다고 가정한다.

 

입력:

첫째 줄에 우리의 크기 N(1<=N<=100,000)이 주어진다.

 

출력:

첫째 줄에 사자를 배치하는 경우의 수를 9901로 나눈 나머지를 출력하여라.

 

풀이 방법:

 dp문제인데 N마다 생성되는 규칙을 찾아내거나 아니면 점화식을 찾으면 된다. 따라서 찾은 점화식은 다음과 같다. 

an = a(n-1) + 2*a(n-2)

따라서 이 규칙에 따라서 값을 구해주면 된다.

1
2
3
4
5
6
7
8
9
10
11
12
n=int(input())
answer=1
first=3
if n==1:
    print(first)
else:
    while n!=1:
        temp=first
        first=(2*first+answer)%9901
        answer=temp
        n-=1
    print(first)
cs

문제 링크:

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

 

728x90
반응형

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

[BOJ]1389. 케빈 베이컨의 6단계 법칙  (0) 2019.08.21
[BOJ]4307. 개미  (0) 2019.08.06
[BOJ]5430. AC  (0) 2019.08.04
[BOJ]2312. 수 복원하기  (0) 2019.08.03
[BOJ]15649. N과M(1),(2)  (0) 2019.08.02
728x90
반응형

문제:

선영이는 주말에 할 일이 없어서 새로운 언어 AC를 만들었다. AC는 정수 배열에 연산을 하기 위해 만든 언어이다. 이 언어에는 두 가지 함수 R(뒤집기)과 D(버리기)가 있다.

 

함수 R은 배열에 있는 숫자의 순서를 뒤집는 함수이고, D는 첫 번째 숫자를 버리는 함수이다. 배열이 비어있는데 D를 사용한 경우에는 에러가 발생한다.

 

함수는 조합해서 한 번에 사용할 수 있다. 예를 들어, "AB"는 A를 수행한 다음에 바로 이어서 B를 수행하는 함수이다. 예를 들어, "RDD"는 배열을 뒤집은 다음 처음 두 숫자를 버린느 함수이다.

 

배열의 초기값과 수행할 함수가 주어졌을 때, 최종 결과를 구하는 프로그램을 작성하시오.

 

입력:

첫째 줄에 테스트 케이스의 개수 T가 주어진다. T는 최대 100이다.

각 테스트 케이스의 첫째 줄에는 수행할 함수 p가 주어진다. p의 길이는 1보다 크거나 같고, 100,000보다 작거나 같다.

다음 줄에는 배열에 들어있는 수의 개수 n이 주어진다. (0<=n<=100,000)

다음 줄에는 [x1,...., xn]과 같은 형태로 배열에 들어 있는 수가 주어진다. (1 <=xi <=100)

전 테스트 케이스에 주어지는 p의 길이의 합과 n의 합은 70만을 넘지 않는다.

 

출력:

각 테스트 케이스에 대해서, 입력으로 주어진 정수 배열에 함수를 수행한 결과를 출력한다. 만약, 에러가 발생한 경우에는 error를 출력한다.

 

풀이 방법:

 명령어를 수행하는 것은 별로 어렵진 않았지만, 이를 위해 사전에 입력값을 전처리하고, 다시 이를 패키징 하는 것이 귀찮았다. 입력이 [1,2,3,4]와 같이 들어오게 되는데 리스트로 들어온다는 것이 아니라, 리스트처럼 생긴 스트링으로 들어오는 것이다. 따라서 이를 구분해서 배열에 담아야 한다. 명령어를 수행하는 것은 비교적 간단하다.

 

 처음에는 R이 들어오면 reverse를 D가 들어오면 pop(0)을 하는 방식으로 진행했더니 시간 초과가 발생하게 되었다. reverse를 하는 연산의 시간이 크다고 해서 이를 줄이기 위해서 마지막에 딱 한 번만 하는 방식으로 바꾸게 되었다.

 

RR이 두 번 들어온다면 두 번 뒤집는 것이기 때문에 결국 다시 처음 배열로 돌아오는 것과 같다. 즉 R이 짝수 번 들어온다면 뒤집을 필요가 없는 것이다. D는 R이 몇 번 나왔는지에 따라 빼는 위치만 달라지게 하면 된다. R이 한 번 나와 뒤집어져 있는 상태라면 맨 앞이 아닌 맨 뒤를 빼야 정상적으로 D의 명령어가 수행되는 것이다. 따라서 이를 구분하기 위해서 ReverseCount를 만들었으며, 비정상적인 명령어를 구분하기 위해서 예외처리 구문과 Error 변수를 만들었다.

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
import sys
for i in range(int(sys.stdin.readline().rstrip())):
    command=sys.stdin.readline().rstrip()
    length=int(sys.stdin.readline().rstrip())
    numbers=sys.stdin.readline().rstrip()[1:-1].split(',')
    temp=[]
    Error=False
    for number in numbers:
        if number.isdigit():
            temp.append(int(number))
    ReverseCount=0
    for j in range(len(command)):
        try:
            if command[j]=="R":
                ReverseCount+=1
            elif command[j]=="D" and ReverseCount%2==0:
                temp.pop(0)
            elif command[j]=="D" and ReverseCount%2==1:
                temp.pop()
        except:
            Error=True
            break
    if ReverseCount%2==1:
        temp.reverse()
    if not Error:
        print("[",end="")
        print(*temp,sep=',',end='')
        print(']')
    else:
        print("error")
cs

문제 링크:

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

 

 

728x90
반응형

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

[BOJ]4307. 개미  (0) 2019.08.06
[BOJ]1309. 동물원  (0) 2019.08.05
[BOJ]2312. 수 복원하기  (0) 2019.08.03
[BOJ]15649. N과M(1),(2)  (0) 2019.08.02
[BOJ]1009. 분산처리  (0) 2019.08.01
728x90
반응형

문제:

양의 정수 N이 주어졌을 때, 이 수를 소인수분해 한 결과를 출력하는 프로그램을 작성하시오.

입력:

첫째 줄에 테스트 케이스의 수가 주어진다. 각 테스트 케이스마다 양의 정수 N (2<=N<=100,000)이 주어진다.

출력:

각 테스트 케이스마다 각 인수와 그 인수가 곱해진 횟수를 한 줄씩 출력한다. 출력 순서는 인수가 증가하는 순으로 한다.

풀이 방법:

소인수분해는 말 그대로 소수로만 분해가 된다. 따라서 2부터 시작해서 n이 1이 될 때까지 소수로 나눠주면 된다. 소수인지 따로 판별이 필요하지 않다.(이전에서 이미 다 나눠버렸기 때문에) 따라서 각 count별로 answer를 계산하고 더 이상 나눠주지 못한다면 초기화를 하고 다음으로 넘어가면 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
for i in range(int(input())):
    n=int(input())
    count=2
    answer = 0
    while n!=1:
        if n%count==0:
            n//=count
            answer+=1
        else:
            if answer==0:
                pass
            else:
                print(count,answer)
            answer=0
            count+=1
    print(count,answer)
cs

문제 링크:

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

728x90
반응형

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

[BOJ]1309. 동물원  (0) 2019.08.05
[BOJ]5430. AC  (0) 2019.08.04
[BOJ]15649. N과M(1),(2)  (0) 2019.08.02
[BOJ]1009. 분산처리  (0) 2019.08.01
[Programmers]Lv 3.배달  (3) 2019.07.31
728x90
반응형

문제:

자연수 N과 M이 주어졌을 때, 아래 조건을 만족하는 길이가 M인 수열을 모두 구하는 프로그램을 작성하시오.

  • 1부터 N까지 자연수 중에서 중복 없이 M개를 고른 수열

입력:

첫째 줄에 자연수 N과 M이 주어진다. (1<= M <= N < 8)

출력:

한 줄에 하나씩 문제의 조건을 만족하는 수열을 출력한다. 중복되는 수열을 여러 번 출력하면 안되며, 각 수열은 공백으로 구분해서 출력해야 한다.
수열은 사전 순으로 증가하는 순서로 출력해야 한다.

풀이 방법:

재귀적인 방법으로 길이가 M이 될 때까지 계속해서 넣어준다. 대신 이 문제에서는 중복을 허용하지 않았기 때문에 이에 대한 조건도 있어야 하고 증가하는 순서로 출력해야 하므로 배열에 들어있는 끝 값보다 클 때만 넣어줘야 한다는 조건 역시 필요하다. 이 문제에 대한 시리즈가 여러개 있는데 이에 맞는 조건을 넣어주면 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
def sequence(stack,numbers,M):
    if len(stack)==M:
        print(*stack)
        return
    else:
        for number in numbers:
            if not number in stack:
                stack.append(number)
                sequence(stack,numbers,M)
                stack.pop()
 
a,b=map(int,input().split())
numbers=list(range(1,a+1))
stack=[]
for number in numbers:
    if not number in stack:
        stack.append(number)
        sequence(stack,numbers,b)
        stack.pop()
cs

문제 링크:

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

728x90
반응형

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

[BOJ]5430. AC  (0) 2019.08.04
[BOJ]2312. 수 복원하기  (0) 2019.08.03
[BOJ]1009. 분산처리  (0) 2019.08.01
[Programmers]Lv 3.배달  (3) 2019.07.31
[Programmers]Lv 3. 순위  (0) 2019.07.30
728x90
반응형

문제:

 재용이는 최신 컴퓨터 10대를 가지고 있다. 어느 날 재용이는 많은 데이터를 처리해야 될 일이 생겨서 각 컴퓨터에 1번부터 10번까지의 번호를 부여하고, 10대의 컴퓨터가 다음과 같은 방법으로 데이터들을 처리하기로 하였다.

 

 1번 데이터는 1번 컴퓨터, 2번 데이터는 2번 컴퓨터, 3번 데이터는 3번 데이터, ....,

 10번 데이터틑 10번 컴퓨터, 11번 데이터는 1번 컴퓨터, 12번데이터는 2번 컴퓨터, ...

 

총 데이터의 개수는 항상 a^b개의 형태로 주어진다. 재용이는 문득 마지막 데이터가 처리될 컴퓨터의 번호가 궁금해졌다. 이를 수행해주는 프로그램을 작성하라.

 

입력:

입력의 첫 줄에는 테스트 케이스의 개수 T가 주어진다. 그 다음 줄부터 각각의 테스트 케이스에 대해 정수 a와 b가 주어진다. (1<=a<100, 1<=b<1,000,000)

 

출력:

각 테스트 케이스에 대해 마지막 데이터가 처리되는 컴퓨터의 번호를 출력한다.

풀이 방법:

 a^b 꼴, 즉 제곱수 형태로 주어지기 때문에 일정한 규칙이 있게 된다. 계속 곱하다 보면 일의 자리가 반복됨을 알 수 있다.

1 -> 1 -> ...

2 -> 4 -> 8 -> 6 -> 2 -> ...

3 -> 9 -> 7-> 1 -> 3 ->...

4 -> 6 -> 4 -> ...

5 -> 5 -> ....

6 -> 6 -> ...

7 -> 9 -> 3 -> 1 -> 7 -> ....

8 -> 4 -> 2 -> 6 -> 8 -> ....

9 -> 1 -> 9 -> ....

10 -> 10 -> ... (원래는 0이겠지만 문제상에서는 10이다.)

따라서 a에 맞는 규칙 배열을 만들어 준 뒤에 b에 맞는 인덱스를 찾아 반환해주면 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
for i in range(int(input())):
    again=[]
    a,b=map(int,input().split())
    if a%10==0:
        print(10)
        continue
    temp=a%10
    while True:
        if not temp in again:
            again.append(temp)
            temp*=a
            temp%=10
        else:
            break
    print(again[b%len(again)-1])
cs

 

문제 링크:

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

728x90
반응형

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

[BOJ]2312. 수 복원하기  (0) 2019.08.03
[BOJ]15649. N과M(1),(2)  (0) 2019.08.02
[Programmers]Lv 3.배달  (3) 2019.07.31
[Programmers]Lv 3. 순위  (0) 2019.07.30
[Programmers]Lv3. 가장 먼 노드  (0) 2019.07.29
728x90
반응형

문제:

 N개의 마을로 이루어진 나라가 있습니다. 이 나라의 각 마을에는 1부터 N까지의 번호가 각각 하나씩 부여되어 있습니다. 각 마을은 양방향으로 통행할 수 있는 도로로 연결되어 있는데, 서로 다른 마을간에 이동할 때는 이 도로를 지나야 합니다. 도로를 지날 때 걸리는 시간은 도로별로 다릅니다. 현재 1번 마을에 있는 음식점에서 각 마을로 음식 배달을 하려고 합니다. 각 마을로부터 음식 주문을 받으려고 하는데, N개의 마을 중에서 K 시간 이하로 배달이 가능한 마을에서만 주문을 받으려고 합니다. 다음은 N=5, K=3인 경우의 예시입니다.
 
 1번 마을에 있는 음식점은 [1,2,4,5]번 마을까지는 3이하의 시간에 배달할 수 있습니다. 그러나 3번 마을까지는 3시간 이내로 배달할 수 있는 경로가 없으므로 3번 마을에서는 주문을 받지 않습니다. 따라서 1번 마을에 있는 음식점이 배달 주문을 받을 수 있는 마을은 4개가 됩니다.
 
 마을의 개수 N, 각 마을을 연결하는 도로의 정보 road, 음식 배달이 가능한 시간 K가 매개변수로 주어질 때, 음식 주문을 받을 수 있는 마을의 개수를 return 하도록 solution 함수를 완성해주세요.
 

풀이 방법:

<Test 32 시간초과>

 DFS 방법을 사용해서 배달 거리가 K를 넘지 않을 때까지 stack 배열에 쌓으면서 계속해서 들어간다. 들어가는 과정에서 방문하는 마을은 모두 K시간 내 방문할 수 있는 곳이므로 count set에 담도록 한다.(set이므로 중복된 것을 넣어도 자동으로 사라진다.) stack 배열을 사용하는 이유는 사이클을 피하기 위해서이므로 깊은 노드를 방문하고 다시 나올 때는 stack에서 pop 하도록해서 다른 노드를 방문할 시간을 주도록 한다. 
 하지만 재귀 과정에서 문제가 발생해서 시간초과가 발생하는 것 같은데 무엇이 문제인지는 정확히 모르겠다. (정렬도 해봤지만 차이가 없었다.)
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
def delivery(stack,dist,now,roads,K):
    for r in roads[now]:
        temp=dist+r[1]
        if not r[0in stack and temp <=K:
            stack.append(r[0])
            count.add(r[0])
            delivery(stack,temp,r[0],roads,K)
            stack.pop()
    
def solution(N,road,K):
    roads=[[]for i in range(N+1)]
    for i in range(len(road)):
        if not road[i][0in roads[road[i][1]]:
            roads[road[i][1]].append((road[i][0],road[i][2]))
        if not road[i][1in roads[road[i][0]]:
            roads[road[i][0]].append((road[i][1],road[i][2]))
    stack=[1]
    dist=0
    global count
    count=set(stack)
    for r in roads[1]:
        temp=dist+r[1]
        if not r[0in stack and temp <=K:
            stack.append(r[0])
            count.add(r[0])
            delivery(stack,temp,r[0],roads,K)
            stack.pop()
    return len(count)
cs

 <2021.07.11 수정>

DFS와 같이 재귀적인 방법을 사용하는 것이 시간을 많이 소요할 것 같아 일반적으로 그래프에서 최소 거리를 구하는 방법으로 많이 사용되는 다익스트라 방법을 사용했다. 1에서 부터의 거리를 측정하기 때문에, 1에서 다익스트라로 거리를 구한 뒤에 K보다 작은 것의 갯수를 세서 반환하도록 한다.

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
import heapq
 
def dijkstra(start,dp,edge):
    dp[start] = 0
    heapq.heappush(heap,(0,start))
    
    while heap:
        weight, move = heapq.heappop(heap)
        
        if dp[move] < weight:
            continue
        for w, node in edge[move]:
            if w+weight< dp[node]:
                dp[node] = w+weight
                heapq.heappush(heap,(dp[node],node))
    return dp
 
def solution(N,road,K):
    edge = [[] for _ in range(N+1)]
    heap = []
    for i in road:
        a,b,c = i
        edge[a].append((c,b))
        edge[b].append((c,a))
    dp = [float('inf')]*(N+1)
    
    dp = dijkstra(1,dp,edge)
    answer = 0
    for i in range(1,V+1):
        if dp[i] <= K:
            answer +=1
    return answer
cs

문제 링크:

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

728x90
반응형

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

[BOJ]15649. N과M(1),(2)  (0) 2019.08.02
[BOJ]1009. 분산처리  (0) 2019.08.01
[Programmers]Lv 3. 순위  (0) 2019.07.30
[Programmers]Lv3. 가장 먼 노드  (0) 2019.07.29
[Programmers]Lv 4. 3xn 타일링  (2) 2019.07.28
728x90
반응형

문제:

n명의 권투선수가 권투 대회에 참여했고 각각 1번부터 n번까지 번호를 받았습니다. 권투 경기는 1대1 방식으로 진행이 되고, 만약 A 선수가 B선수보다 실력이 좋다면 A 선수는 B 선수를 항상 이깁니다. 심판은 주어진 경기 결과를 가지고 선수들의 순위를 매기려 합니다. 하지만 몇몇 경기 결과를 분실하여 정화하게 순위를 매길 수 없습니다.

선수의 수 n, 경기 결과를 담은 2차원 배열 results가 매개변수로 주어질 때 정확하게 순위를 매길 수 있는 선수의 수를 return 하도록 solution 함수를 작성해주세요.

풀이 방법:

 각 선수가 이긴 선수와 진 선수의 정보를 hash방식으로 정리하고 한 선수의 win정보의 길이와 lose정보 길이를 합쳤을 때 n-1과 같아지면 그 선수의 순위를 알 수 있게 된다. 또한 실력의 차이가 극명해서 실력이 낮은 사람이 높은 사람을 이길 수 없다고 한다. 따라서 정보를 가지고 있지 않지만 이 조건을 통해서 정보를 다시 얻을 수 있게 된다.

 입출력 예시를 통해서 살펴 보면 2번선수의 경우에는 모든 경기기록이 있어서 순위를 알 수 있지만 5번 선수는 2번 선수와의 기록이 있지만 순위를 유추할 수 있다. 왜냐하면 2번이 1,3,4번 선수한테 졌는데 5번이 2번한테 졌으므로 5번은 당연히 1,3,4번 선수한테 진다는 것을 알 수 있다.(1,3,4 > 2 > 5) 또한 2번이 5번을 이겼기 때문에 5번이 이긴 사람도 당연히 이길 수 있다. (이 문제에서는 이러한 케이스가 없긴 하다.)

 처음에는 리스트로 했더니 시간초과가 발생해서 이를 set으로 바꿔서 했더니 시간초과가 발생하지 않았다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
def solution(n, results):
    answer=0
    win={}
    lose={}
    for i in range(1,n+1):
        win[i]=set()
        lose[i]=set()
    results.sort()
    for i in range(1,n+1):
        for re in results:
            if re[0]==i:
                win[i].add(re[1])
            if re[1]==i:
                lose[i].add(re[0])
        for j in win[i]:
            lose[j].update(lose[i])
        for j in lose[i]:
            win[j].update(win[i])
    for i in range(1,n+1):
        if len(win[i])+len(lose[i])==n-1:
            answer+=1
    return answer
cs

문제 링크:



728x90
반응형

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

[BOJ]1009. 분산처리  (0) 2019.08.01
[Programmers]Lv 3.배달  (3) 2019.07.31
[Programmers]Lv3. 가장 먼 노드  (0) 2019.07.29
[Programmers]Lv 4. 3xn 타일링  (2) 2019.07.28
[BOJ]2805. 나무 자르기  (0) 2019.07.27
728x90
반응형

문제:

 n개의 노드가 있는 그래프가 있습니다. 각 노드는 1부터 n까지 번호가 적혀있습니다. 1번 노드에서 가장 멀리 떨어진 노드의 갯수를 구하려고 합니다. 가장 멀리 떨어진 노드란 최단경로로 이동했을 때 간선의 개수가 가장 많은 노드들을 의미합니다. 

 노드의 개수 n, 간선의 대한 정보가 담신 2차우너 배열 vertex가 매개변수로 주어질 때, 1번 노드로부터 가장 멀리 떨어진 노드가 몇 개인지를 return 하도록 solution 함수를 작성해주세요.

풀이 방법:

 노드들의 최소경로 값을 나타내는 answer를 만든 뒤에 BFS 방식으로 노드들을 검사한다. 노드를 방문할 때마다 해당 node의 answer 값이 0이면 count로 초기화 해주고, count는 한 층을 더 들어갈 때 마다 1씩 증가하도록 했다. 이렇게 모든 answer가 0이 아닌 값으로 변하면(all) answer의 max값을 찾아서 max로 count를 해 답을 얻을 수 있다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
def solution(n, edge):
    answer = [0]*(n+1)
    newedge=[[] for i in range(len(edge)+1)]
    for i in range(len(edge)):
        if not edge[i][1in newedge[edge[i][0]]:
            newedge[edge[i][0]].append(edge[i][1])
            newedge[edge[i][0]].sort()
        if not edge[i][0in newedge[edge[i][1]]:
            newedge[edge[i][1]].append(edge[i][0])
            newedge[edge[i][1]].sort()
    answer[0],answer[1]= -1,-1
    queue=[1]
    count=1
    while not all(answer):
        temp=[]
        for start in queue:
            for i in newedge[start]:
                if answer[i] ==0:
                    answer[i]+=count
                    temp.append(i)
        queue=temp
        count+=1
    ans=answer.count(max(answer))
    return ans
cs

문제 링크:


728x90
반응형

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

[Programmers]Lv 3.배달  (3) 2019.07.31
[Programmers]Lv 3. 순위  (0) 2019.07.30
[Programmers]Lv 4. 3xn 타일링  (2) 2019.07.28
[BOJ]2805. 나무 자르기  (0) 2019.07.27
[BOJ]1654.랜선 자르기  (0) 2019.07.26
728x90
반응형

문제:

가로 길이가 2이고 세로의 길이가 1인 직사각형 모양의 타일이 있습니다. 이 직사각형 타일을 이용하여 세로의 길이가 3이고 가로의 길이가 n인 바닥을 가득 채우려고 합니다. 타일을 채울 때는 다음과 같이 2가지 방법이 있습니다.
  *타일을 가로로 배치하는 경우
  *타일을 세로로 배치하는 경우
직사각형의 가로의 길이 n이 매개변수로 주어질 때, 이 직사각형을 채우는 방법의 수를 return 하는 solution 함수를 완성해주세요.

풀이 방법:

 이전 단계인 2xn 타일링과 같이 동적계획법을 사용해서 풀어야 하는 문제이다. n이 증가할 때마다 어떠한 규칙에 따라서 증가하는지 파악할 수 있다면 쉽게 문제를 풀 수 있다. n이 6~8까지 그려보면 대충 규칙을 찾아낼수 있다. 우선 n이 홀수 일 때는 타일링을 할 수 없다. 따라서 이 경우에는 항상 0이다.
그리고 타일로 만들 수 있는 모양이 한정적이라서 그 모양들을 여러 개 붙인 모양으로 반복이 된다. 규칙이 있는 타일은 다음과 같다.


 이 타일들의 조합으로 반복이 되며 n=4일 때부터는 추가적인 몇개의 조합이 더 생기게 된다. 이는 이전 n(짝수만 생각했을 때)과 연관이 있기 때문에 다음과 같이 코드를 짤 수 있다.


1
2
3
4
5
6
7
8
9
def solution(n):
    dp=[0]*(n+1)
    dp[0]=1
    special=0
    for i in range(2,n+1,2):
        dp[i]=dp[i-2]*3+special*2
        special+=dp[i-2]
    answer = dp[n]%1000000007
    return answer
cs

문제 링크:

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

728x90
반응형

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

[Programmers]Lv 3. 순위  (0) 2019.07.30
[Programmers]Lv3. 가장 먼 노드  (0) 2019.07.29
[BOJ]2805. 나무 자르기  (0) 2019.07.27
[BOJ]1654.랜선 자르기  (0) 2019.07.26
[BOJ]10816. 숫자 카드2  (0) 2019.07.25
728x90
반응형

문제:

상근이는 나무 M미터가 필요하다. 근처에 나무를 구입할 곳이 모두 망해버렸기 때문에, 정부에 벌목 허가를 요청했다. 정부는 상근이네 집 근처의 나무 한 줄에 대한 벌목 허가를 내주었고, 상근이는 새로 구입한 목재절단기를 이용해서 나무를 구할 것이다.

목재절단기를 다음과 같이 동작한다. 먼저, 상근이는 절단기에 높이 H를 지정해야 한다. 높이를 지정하면 톱날이 땅으로부터 H미터 위로 올라간다. 그 다음, 한 줄에 연속해있는 나무를 절단해버린다. 따라서, 높이가 H보다 큰 나무는 H 위의 부분이 잘릴 것이고, 낮은 나무는 잘리지 않을 것이다. 예를 들어, 한 줄에 연속해있는 나무의 높이가 20,15,10,17이라고 하자. 상근이가 높이를 15로 지정했다면, 나무를 자른 뒤의 높이는 15,15,10,15가 될 것이고, 상근이는 길이가 5인 나무와 2인 나무를 들고 집에 갈 것이다. (총 7미터를 집에 들고 간다.)


상근이는 환경에 매우 관심이 많기 때문에, 나무를 필요한 만큼만 집으로 가져가려고 한다. 이 때, 적어도 M미터의 나무를 집에 가져가지 위해서 절단기에 설정할 수 있는 높이의 최댓값을 구하는 프로그램을 작성하시오.

입력:

첫째 줄에 나무의 수 N과 상근이가 집으로 가져가려고 하는 나무의 길이 M이 주어진다. (1<=N<=1,000,000, 1<=M<=2,000,000,000)
둘째 줄에는 나무의 높이가 주어진다. 나무의 높이의 합은 항상 M을 넘기 때문에, 상근이는 집에 필요한 나무를 항상 가져갈 수 있다. 높이는 1,000,000,000보다 작거나 같은 양의 정수 또는 0이다.

출력:

적어도 M미터의 나무를 집에 가져가기 위해서 절단기에 설정할 수 있는 높이의 최댓값을 출력한다.

풀이 방법:

이 문제도 이분탐색(파라메트릭서치)를 사용해서 풀어야 하는 문제다. left를 1, right를 max(trees)로 잡고 나서 그 사이의 값을 찍어가면서 M보다 커질 때마다 mid을 비교해 최대값을 찾도록 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
k,n=map(int,input().split())
trees=list(map(int,input().split()))
left=1
right=max(trees)
answer=0
while left <= right:
    count=0
    mid=(left+right)//2
    for tree in trees:
        if tree-mid > 0:
            count+=tree-mid
    if count==n:
        if answer < mid:
            answer=mid
        left=mid+1
    elif count < n:
        right=mid-1
    else:
        if answer < mid:
            answer=mid
        left=mid+1
print(answer)
cs

문제 링크:


728x90
반응형

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

[Programmers]Lv3. 가장 먼 노드  (0) 2019.07.29
[Programmers]Lv 4. 3xn 타일링  (2) 2019.07.28
[BOJ]1654.랜선 자르기  (0) 2019.07.26
[BOJ]10816. 숫자 카드2  (0) 2019.07.25
[BOJ]1920. 수 찾기  (0) 2019.07.24

+ Recent posts