문제:

풀이방법:

투 포인터를 사용해서 문제를 해결하도록 한다.

s,e 두 개의 포인터를 사용하며 K보다 작다면 e를 계속해서 증가시키고, k와 같아진 경우 answer를 조건에 맞게 최신화한다. 이 과정이 끝나면 s를 증가시켜 다음 탐색을 진행한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
def solution(sequence, k):
    answer = []
    L = len(sequence)
    s, e = 00
    parse_sum = sequence[0]
    for s in range(L):
        while e + 1 < L and parse_sum < k:
            e += 1
            parse_sum += sequence[e]
        if parse_sum == k:
            if not answer:
                answer = [s, e]
            else:
                ans_s, ans_e = answer
                if e-< ans_e-ans_s:
                    answer = [s, e]
        parse_sum-=sequence[s]
    return answer
cs

문제링크:

https://school.programmers.co.kr/learn/courses/30/lessons/178870

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

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

[BOJ] 19941. 햄버거 분배  (0) 2023.07.20
[BOJ] 20920. 영단어 암기는 괴로워  (0) 2023.07.19
[BOJ] 21921. 블로그  (0) 2023.07.17
[Programmers] Lv 2. 롤케이크 자르기  (0) 2023.07.14
[BOJ] 1111. IQ Test  (0) 2023.07.13

문제:

주몽은 철기군을 양성하기 위한 프로젝트에 나섰다. 그래서 야철대장을 통해 철기군이 입을 갑옷을 만들게 하였다. 야철대장은 주몽의 명에 따르기 위하여 연구에 착수하던 중 아래와 같은 사실을 발견하게 되었다.

갑옷을 만드는 재료들은 각각 고유한 번호를 가지고 있다. 갑옷은 두 개의 재료로 만드는데 두 재료의 고유한 번호를 합쳐서 M(1 ≤ M ≤ 10,000,000)이 되면 갑옷이 만들어 지게 된다. 야철대장은 자신이 만들고 있는 재료를 가지고 갑옷을 몇 개나 만들 수 있는지 궁금해졌다. 이러한 궁금증을 풀어 주기 위하여 N(1 ≤ N ≤ 15,000) 개의 재료와 M이 주어졌을 때 몇 개의 갑옷을 만들 수 있는지를 구하는 프로그램을 작성하시오.

입력:

첫째 줄에는 재료의 개수 N(1 ≤ N ≤ 15,000)이 주어진다. 그리고 두 번째 줄에는 갑옷을 만드는데 필요한 수 M(1 ≤ M ≤ 10,000,000) 주어진다. 그리고 마지막으로 셋째 줄에는 N개의 재료들이 가진 고유한 번호들이 공백을 사이에 두고 주어진다. 고유한 번호는 100,000보다 작거나 같은 자연수이다.

출력:

첫째 줄에 갑옷을 만들 수 있는 개수를 출력한다.

풀이방법:

 우선 N개의 재료들을 오름차순으로 정렬하고, 첫 값(start)과 마지막 값(end)에 포인터를 할당한다. 그리고 해당 위치에 있는 값들을 더하면서 M이 되는지 확인하고, 만약 M보다 크다면 end의 값을 줄이고, M보다 작거나 같다면 start를 하나 늘리도록 한다. 이 과정을 start와 end가 같아질 때까지 반복하도록 한다.(같은 순간에 종료)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
= int(input())
= int(input())
numbers = sorted(list(map(int,input().split())))
 
answer = 0
start, end = 0, N-1
while start < end:
    if (numbers[start]+numbers[end])==M:
        answer+=1
        start+=1
    elif (numbers[start]+numbers[end]) < M:
        start+=1
    else:
        end-=1
print(answer)
cs

문제링크:

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

 

1940번: 주몽

첫째 줄에는 재료의 개수 N(1 ≤ N ≤ 15,000)이 주어진다. 그리고 두 번째 줄에는 갑옷을 만드는데 필요한 수 M(1 ≤ M ≤ 10,000,000) 주어진다. 그리고 마지막으로 셋째 줄에는 N개의 재료들이 가진 고

www.acmicpc.net

 

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

[BOJ]2828. 사과 담기 게임  (0) 2022.06.28
[BOJ]3986. 좋은 단어  (0) 2022.06.23
[BOJ]1213. 팰린드롬 만들기  (0) 2022.06.16
[BOJ] 9996. 한국이 그리울 땐 서버에 접속하지  (0) 2022.06.14
[BOJ]2437. 저울  (0) 2022.06.02

문제:

KOI 부설 과학연구소에서는 많은 종류의 산성 용액과 알칼리성 용액을 보유하고 있다. 각 용액에는 그 용액의 특성을 나타내는 하나의 정수가 주어져있다.  산성 용액의 특성값은 1부터 1,000,000,000까지의 양의 정수로 나타내고, 알칼리성 용액의 특성값은 -1부터 -1,000,000,000까지의 음의 정수로 나타낸다.

같은 양의 두 용액을 혼합한 용액의 특성값은 혼합에 사용된 각 용액의 특성값의 합으로 정의한다. 이 연구소에서는 같은 양의 두 용액을 혼합하여 특성값이 0에 가장 가까운 용액을 만들려고 한다. 

예를 들어, 주어진 용액들의 특성값이 [-2, 4, -99, -1, 98]인 경우에는 특성값이 -99인 용액과 특성값이 98인 용액을 혼합하면 특성값이 -1인 용액을 만들 수 있고, 이 용액이 특성값이 0에 가장 가까운 용액이다. 참고로, 두 종류의 알칼리성 용액만으로나 혹은 두 종류의 산성 용액만으로 특성값이 0에 가장 가까운 혼합 용액을 만드는 경우도 존재할 수 있다.

산성 용액과 알칼리성 용액의 특성값이 주어졌을 때, 이 중 두 개의 서로 다른 용액을 혼합하여 특성값이 0에 가장 가까운 용액을 만들어내는 두 용액을 찾는 프로그램을 작성하시오.

입력:

첫째 줄에는 전체 용액의 수 N이 입력된다. N은 2 이상 100,000 이하이다. 둘째 줄에는 용액의 특성값을 나타내는 N개의 정수가 빈칸을 사이에 두고 주어진다. 이 수들은 모두 -1,000,000,000 이상 1,000,000,000 이하이다. N개의 용액들의 특성값은 모두 다르고, 산성 용액만으로나 알칼리성 용액만으로 입력이 주어지는 경우도 있을 수 있다.

출력:

첫째 줄에 특성값이 0에 가장 가까운 용액을 만들어내는 두 용액의 특성값을 출력한다. 출력해야 하는 두 용액은 특성값의 오름차순으로 출력한다. 특성값이 0에 가장 가까운 용액을 만들어내는 경우가 두 개 이상일 경우에는 그 중 아무것이나 하나를 출력한다.

풀이방법:

 투 포인터를 양쪽 끝값에 두고, 하나씩 이동시키면서 0에 가장 가까운 용액을 만들어 나가도록 한다. 포인터에 있는 값을 비교하고, start 값이 크다면 start를 이동하고, end가 크다면 end를 이동시키도록 한다. 이렇게 생성되는 용액의 특성값과 포인터 값들을 min_heap 정렬해두고, 모든 탐색을 마친 뒤에 min heap의 첫 값을 가져와서 출력하도록 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import heapq
answer = []
= int(input())
solution = sorted(list(map(int,input().split())))
start, end = 0, N-1
while start < end:
    tmp = solution[start]+solution[end]
    if abs(solution[start]) > abs(solution[end]):
        heapq.heappush(answer,(abs(tmp),start,end))
        start+=1
    else:
        heapq.heappush(answer,(abs(tmp),start,end))
        end-=1
answer = heapq.heappop(answer)
print(solution[answer[1]],solution[answer[2]])
cs

문제링크:

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

 

2470번: 두 용액

첫째 줄에는 전체 용액의 수 N이 입력된다. N은 2 이상 100,000 이하이다. 둘째 줄에는 용액의 특성값을 나타내는 N개의 정수가 빈칸을 사이에 두고 주어진다. 이 수들은 모두 -1,000,000,000 이상 1,000,00

www.acmicpc.net

 

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

[BOJ] 14890. 경사로  (0) 2021.09.15
[BOJ]14719. 빗물  (0) 2021.09.14
[BOJ]1655. 가운데를 말해요  (0) 2021.09.10
[BOJ]2110. 공유기 설치  (0) 2021.09.09
[BOJ]17406. 배열 돌리기 4  (0) 2021.09.08

문제:

N과 L이 주어질 때, 합이 N이면서, 길이가 적어도 L인 가장 짧은 연속된 음이 아닌 정수 리스트를 구하는 프로그램을 작성하시오.

입력:

첫째 줄에 N과 L이 주어진다. N은 1,000,000,000보다 작거나 같은 자연수이고, L은 2보다 크거나 같고, 100보다 작거나 같은 자연수이다.

출력:

만약 리스트의 길이가 100보다 작거나 같으면, 연속된 수를 첫째 줄에 공백으로 구분하여 출력한다. 만약 길이가 100보다 크거나 그러한 수열이 없을 때는 -1을 출력한다.

풀이방법:

 처음에는 이 문제를 투포인터를 사용하는 방법으로 접근하였다. list의 합이 N과 같으면 길이를 비교하여 저장하도록 하였고, N보다 작으면 리스트의 길이를 늘려주고 N보다 크면 리스트의 길이를 줄여주도록 하였다.

 하지만 이 방법은 N의 크기에 따라 시간이 많이 증가할 수 있다는 단점을 가지고 있었고 결국 시간초과가 발생하게 되었다. 코드는 다음과 같다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import copy
N, L = map(int,input().split())
 
list_ = list(range(1,L+1))
start, end = 1,L
answer = [0]*100
while list_[0<= N//2:
    if sum(list_) == N:
        if len(list_) < len(answer):
            answer = copy.deepcopy(list_)
            list_.pop(0)
    elif sum(list_) < N:
        list_.append(end)
        end+= 1
    else:
        list_.pop(0)
        start+= 1
if len(answer) > 100 or len(answer) < L:
    print(-1)
else:
    print(*answer)
cs

따라서 다른 방법을 생각해보았는데, 이 문제를 수학적으로 접근해보았다. 

우선 길이가 L인 연속된 수들의 합이 N이 되는 수열은 항상 존재한다고 가정한다. 그리고 그 수열의 첫 시작 수를 X라고 할 때, 다음과 같이 식을 표현할 수 있다.

 

N = X + (X+1) + (X+2) + (X+3) + ... + (X+L-1)

 

이를 정리하면 다음과 같이 표현할 수 있다.

 

N = LX + (1+2+3+...+L-1)

   = LX + (L-1)L/2

 

그럼 X는 다음과 같이 구할 수 있다.

 

X = N/L - (L-1)/2

 

따라서 L을 증가 시키면서, 음이 아닌 정수가 되는 X를 찾으면 된다. 그리고 만약 L이 100이 넘어간다면 -1을 문제 조건에 따라 출력하도록 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
N, L = map(int,input().split())
 
answer = -1
while True:
    if L > 100:
        break
    temp = N/L-(L-1)/2
    if temp < 0:
        L+=1
        continue
    if int(temp) == temp:
        answer = int(temp)
        break
    L+=1
if answer >= 0:
    print(*range(answer,answer+L))
else:
    print(-1)
cs

문제링크:

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

 

1024번: 수열의 합

첫째 줄에 N과 L이 주어진다. N은 1,000,000,000보다 작거나 같은 자연수이고, L은 2보다 크거나 같고, 100보다 작거나 같은 자연수이다.

www.acmicpc.net

 

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

[BOJ]2240. 자두나무  (0) 2021.06.08
[BOJ]2302. 극장 좌석  (0) 2021.06.03
[BOJ]1826. 연료 채우기  (0) 2021.05.27
[BOJ]1422. 숫자의 신  (0) 2021.05.25
[BOJ]15686. 치킨 배달  (0) 2021.05.20

문제:

n개의 서로 다른 양의 정수 a1, a2, ..., an으로 이루어진 수열이 있다. ai의 값은 1보다 크거나 같고, 1000000보다 작거나 같은 자연수이다. 자연수 x가 주어졌을 때, ai + aj = x (1 ≤ i < j ≤ n)을 만족하는 (ai, aj)쌍의 수를 구하는 프로그램을 작성하시오.

입력:

첫째 줄에 수열의 크기 n이 주어진다. 다음 줄에는 수열에 포함되는 수가 주어진다. 셋째 줄에는 x가 주어진다. (1 ≤ n ≤ 100000, 1 ≤ x ≤ 2000000)

출력:

문제의 조건을 만족하는 쌍의 개수를 출력한다.

풀이방법:

 앞에서부터 시작하는 포인터와 뒤에서부터 시작하는 포인터 두 개를 사용해서 합이 x가 되는 점들을 찾는다. 탐색이 종료되는 조건은 포인터가 교차하는 순간이며, 탐색하기 전에 정렬을 하도록 한다.

 

포인터의 이동은 다음과 같은 조건에 따른다.

 1. 두 포인터의 값이 x와 같다면, 양 포인터를 모두 이동시킨다.

 2. x보다 작다면 앞 포인터를 움직여 값을 키운다. 

 3. x보다 크다면 뒷 포인터를 움직여 값을 낮춘다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
= int(input())
numbers = list(map(int,input().split()))
numbers = sorted(numbers)
= int(input())
first, second = 0,n-1
answer = 0
while True:
    if first == second or first > second or second < first:
        break
    now = numbers[first]+numbers[second]
    if now == x:
        answer+=1
        first+=1
        second-=1
    elif now < x:
        first +=1
    else:
        second -=1
 
print(answer)
cs

문제링크:

www.acmicpc.net/problem/3273

 

3273번: 두 수의 합

n개의 서로 다른 양의 정수 a1, a2, ..., an으로 이루어진 수열이 있다. ai의 값은 1보다 크거나 같고, 1000000보다 작거나 같은 자연수이다. 자연수 x가 주어졌을 때, ai + aj = x (1 ≤ i < j ≤ n)을 만족하는

www.acmicpc.net

 

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

[BOJ]3055. 탈출  (0) 2021.05.11
[BOJ]2630. 색종이 만들기  (0) 2021.04.29
[BOJ]9184. 신나는 함수 실행  (0) 2021.04.22
[BOJ]2981. 검문  (0) 2021.04.20
[BOJ]10819. 차이를 최대로  (0) 2021.02.25

문제:

N개의 수로 된 수열 A[1], A[2], …, A[N] 이 있다. 이 수열의 i번째 수부터 j번째 수까지의 합 A[i] + A[i+1] + … + A[j-1] + A[j]가 M이 되는 경우의 수를 구하는 프로그램을 작성하시오.

입력:

첫째 줄에 N(1 ≤ N ≤ 10,000), M(1 ≤ M ≤ 300,000,000)이 주어진다. 다음 줄에는 A[1], A[2], …, A[N]이 공백으로 분리되어 주어진다. 각각의 A[x]는 30,000을 넘지 않는 자연수이다.

출력:

첫째 줄에 경우의 수를 출력한다.

풀이방법:

 포인터 두 개를 활용해서 해결할 수 있는 문제다. start와 end 포인터 두 개를 만든다. start가 문제의 i를 의미하고, j가 문제의 j를 의미하게 된다.

 이 두 포인터를 사용해서 구간 합을 얻고, 이 구간 합이 원하는 값 M보다 작다면 end 포인터를 증가시켜서 구간 합이 커지도록 한다. 만약 M보다 크거나 같다면, start 포인터를 증가시켜서 구간 합이 작아지도록 한다.

 두 포인터의 이동이 종료되는 조건은 end 포인터가 N이 될 때(IndexError가 발생하지 않게 하기 위함), 혹은 start 포인터가 end 포인터를 앞지를 때 종료하도록 한다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
n,m = map(int,input().split())
numbers = list(map(int,input().split()))
 
answer = 0
start,end = 0,0
summation = 0
while True:    
    if summation<m:
        if end==n:
            break
        summation+=numbers[end]
        end+=1
    else:
        summation-=numbers[start]
        start+=1
        if start>end:
            break
    if summation==m:
        answer+=1
 
print(answer)
cs

문제링크:

www.acmicpc.net/problem/2003

 

2003번: 수들의 합 2

첫째 줄에 N(1 ≤ N ≤ 10,000), M(1 ≤ M ≤ 300,000,000)이 주어진다. 다음 줄에는 A[1], A[2], …, A[N]이 공백으로 분리되어 주어진다. 각각의 A[x]는 30,000을 넘지 않는 자연수이다.

www.acmicpc.net

 

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

[BOJ]1715. 카드 정렬하기  (0) 2021.01.28
[BOJ]2529. 부등호  (0) 2021.01.26
[BOJ]2661. 좋은 수열  (0) 2021.01.14
[BOJ]15711. 환상의 짝꿍  (0) 2021.01.12
[BOJ]14938. 서강그라운드  (0) 2021.01.07

문제:

하나 이상의 연속된 소수의 합으로 나타낼 수 있는 자연수들이 있다. 몇 가지 자연수의 예를 들어 보면 다음과 같다.

 

- 3 : 3 (한 가지)

- 41 : 2+3+5+7+11+13 = 11+13+17 = 41 (세 가지)

- 53 : 5+7+11+13+17 = 53 (두 가지)

 

하지만 연속된 소수의 합으로 나타낼 수 없는 자연수들도 있는데, 20이 그 예이다. 7+13을 계산하면 20이 되기는 하나 7과 13이 연속이 아니기에 적합한 표현이 아니다. 또한 한 소수는 반드시 한 번만 덧셈에 사용될 수 있기 때문에, 3+5+5+7과 같은 표현도 적합하지 않다.

 

자연수가 주어졌을 때, 이 자연수를 연속된 소수의 합으로 나타낼 수 있는 경우의 수를 구하는 프로그램을 작성하시오.

입력:

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

출력:

첫째 줄에 자연수 N을 연속된 소수의 합으로 나타낼 수 있는 경우의 수를 출력한다.

풀이방법:

투 포인터를 사용하는 슬라이딩 윈도우랑 소수를 구하는 알고리즘 중 하나인 에라토스테네스의 체를 사용하도록 한다.

우선 자연수 N 이하의 소수들을 에라토스테네스의 체를 이용해서 찾는다. 이 때, 소수인 값들만 남기기 위해서 set을 사용해서 소수가 아닌 것들을 제거하도록 했다.

이렇게 자연수 N 이하의 소수들이 담긴 배열을 구했으면, 이를 투 포인터를 이용한 슬라이딩 윈도우를 통해서 부분합을 구한다. 자연수 N보다 부분합이 작다면 end를 움직여서 부분합을 증가시키고, 부분합이 더 크다면 start를 줄여서 부분합을 증가시킨다.

N이 되는 경우는 count를 1씩 늘리며 부분합을 줄이도록 한다.

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
= int(input())
 
def sosu(N):
    numbers = [1]*(N+1)
    numbers[0]=0
    numbers[1]=0
    for idx in range(2,len(numbers)):
        if numbers[idx] == 0:
            continue
        else:
            numbers[idx]=idx
            temp = idx+idx
            while temp <= N:
                numbers[temp]=0
                temp+=idx
    return sorted(list(set(numbers)))
            
 
so = sosu(N)
so.remove(0)
if len(so)==0:
    print(0)
else:
    start,end=0,0
    count=0
    answer = so[start]
    while start<=end:
        if answer < N:
            end+=1
            if end >=len(so):
                break
            answer += so[end]
        elif answer >N:
            answer-=so[start]
            start+=1
        else:
            count+=1
            answer-=so[start]
            start+=1
 
    print(count)
cs

 

문제링크:

www.acmicpc.net/problem/1644

 

1644번: 소수의 연속합

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

www.acmicpc.net

 

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

[BOJ]1786. 찾기  (0) 2020.10.27
[BOJ]19948. 음유시인 영재  (0) 2020.10.15
[BOJ]12100. 2048(Easy)  (0) 2020.09.24
[BOJ]1806 부분합  (0) 2020.09.22
[BOJ]2096. 내려가기  (0) 2020.09.15

+ Recent posts