HelloMinchan
처음처럼
HelloMinchan
LinkedIn
전체 방문자
오늘
어제
  • 분류 전체보기 (306)
    • Backend (4)
      • NestJS (1)
      • Express (1)
      • Spring (2)
    • Infrastructure (1)
      • AWS (1)
    • Frontend (1)
      • Next.js (1)
    • Language & Runtime (4)
      • Java (2)
      • Node.js (2)
    • Computer Science (8)
      • Computer Networks (3)
      • Operating Systems (4)
      • OOP (1)
    • 독서 (4)
      • 데이터 중심 애플리케이션 설계 (3)
      • 객체지향의 사실과 오해 (1)
    • 회고 (4)
      • Project (2)
      • Career (2)
    • Deprecated (280)

채널

  • GitHub
  • LinkedIn

최근 글

태그

  • Baekjoon Online Judge
  • Algospot
  • 프로그래밍
  • front-end
  • 알고스팟Python
  • 백엔드
  • 백준
  • 프로그래머스
  • 코딩
  • 프로그래머스Python
  • 데이터베이스
  • 알고스팟
  • 백준Go
  • back-end
  • 개발자
  • 백준Python
  • 백준C++
  • programmers
  • Database
  • 프로그래머스C++

최근 댓글

인기 글

hELLO
HelloMinchan

처음처럼

[Baekjoon Online Judge] 백준 3090번 차이를 최소로(C++, Python)
Deprecated

[Baekjoon Online Judge] 백준 3090번 차이를 최소로(C++, Python)

2020. 4. 12. 01:53

© 2020 All Rights Reserved. 주식회사 스타트링크

[Baekjoon Online Judge] 백준 3090번 차이를 최소로

(C++, Python)

(글쓴날 : 2020.04.12)

 


* Baekjoon Online Judge, 백준 3090번 문제 C++, Python 언어 풀이입니다.

* 소스 코드의 저작권은 글쓴이에게 있습니다.


 

 

백준 3090번 차이를 최소로


1) 문제

문제 링크 : https://www.acmicpc.net/problem/3090

 

3090번: 차이를 최소로

문제 정수 N개로 이루어진 배열 A가 주어진다. 상근이는 수열의 수 하나를 골라서 값을 1 감소시킬 수 있다. 단, 수는 1보다 작아질 수 없다. 상근이는 위의 감소시키는 연산을 최대 T번 하려고 한다. 이때, 인접한 수의 차이의 최댓값을 최소로 하는 프로그램을 출력하시오. 입력 첫째 줄에 N과 T가 주어진다.(2 ≤ N ≤ 100 000, 1 ≤ T ≤ 109) 둘째 줄에는 배열에 들어있는 수가 주어진다. (109보다 작은 자연수) 출력 첫째 줄에 인접

www.acmicpc.net


2) 풀이 과정

N개의 정수로 이루어진 배열이 주어지고 최대 T번 배열의 숫자를 1씩 감소시킬 때, 인접한 수들의 차이의 최댓값이 최소가 되는 배열의 값들을 구하는 문제입니다.

 

저의 경우, 이분 탐색을 적용하여 문제에 접근하였으며, C++과 Python을 사용했습니다.

이분 탐색의 mid 값을 인접한 수들의 차이의 최댓값으로 설정하였고, T번안에 해당 차이만큼의 배열을 만들 수 있는지를 조사하는 investigate() 함수를 만들었습니다.

investigate() 함수에서는 두 번의 반복문으로 배열의 값을 감소시키는데, 첫 번째 반복문의 경우, → 방향으로 현재 인덱스의 오른쪽 수를 대상으로 하여 인자로 넘겨받은 차이만큼 감소시키고, 두 번째 반목문의 경우, ← 방향으로 현재 인덱스의 왼쪽 수를 대상으로 하여 똑같이 인자로 받은 차이만큼 감소시킵니다.

두 반복문에서 감소 연산이 발생할 때마다 operCount 변수에 감소시킨 횟수를 저장하였고, 반복문 종료 후 T와 비교하여 해당 차이만큼 배열을 만들 수 있는지 판단하는 과정을 반복하여 문제를 해결했습니다.


3) 코드

 

* C++ 코드

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
#include <iostream>
#include <vector>
#include <algorithm>
 
using namespace std;
int N, T;
vector<int> arr, tempArr, result;
 
bool investigate(int gap)
{
    tempArr.clear();
    tempArr.resize(N, 0);
    copy(arr.begin(), arr.end(), tempArr.begin());
    int operCount = 0;
 
    for (int i = 0; i < N - 1; i++)
    {
        if (tempArr[i + 1] - tempArr[i] > gap)
        {
            operCount += tempArr[i + 1] - (tempArr[i] + gap);
            tempArr[i + 1] = tempArr[i] + gap;
        }
    }
 
    for (int i = N - 1; i > 0; i--)
    {
        if (tempArr[i - 1] - tempArr[i] > gap)
        {
            operCount += tempArr[i - 1] - (tempArr[i] + gap);
            tempArr[i - 1] = tempArr[i] + gap;
        }
    }
 
    if (operCount <= T)
        return true;
    return false;
}
 
int main(void)
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
 
    cin >> N >> T;
    arr.resize(N, 0);
    result.resize(N, 0);
 
    for (int i = 0; i < N; i++)
        cin >> arr[i];
 
    int left = 0;
    int right = 1000000000;
    int mid = 0;
 
    while (left <= right)
    {
        mid = (left + right) / 2;
 
        if (investigate(mid))
        {
            copy(tempArr.begin(), tempArr.end(), result.begin());
            right = mid - 1;
        }
        else
            left = mid + 1;
    }
 
    for (int i = 0; i < N; i++)
        cout << result[i] << " ";
 
    return 0;
}

* Python 코드

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
import sys, copy
input = sys.stdin.readline
 
N, T = map(int, input().split())
arr = list(map(int, input().split()))
 
 
def investigate(gap):
    global tempArr
    tempArr = copy.deepcopy(arr)
    operCount = 0
 
    for i in range(N - 1):
        if tempArr[i + 1] - tempArr[i] > gap:
            operCount += tempArr[i + 1] - (tempArr[i] + gap)
            tempArr[i + 1] = tempArr[i] + gap
    
    for i in range(N - 1, 0, -1):
        if tempArr[i - 1] - tempArr[i] > gap:
            operCount += tempArr[i - 1] - (tempArr[i] + gap)
            tempArr[i - 1] = tempArr[i] + gap
    
    if operCount <= T:
        return True
    return False
 
 
left = 0
right = 1000000000
result = []
 
while left <= right:
    mid = (left + right) // 2
 
    if investigate(mid):
        result = copy.deepcopy(tempArr)
        right = mid - 1
    else:
        left = mid + 1
 
print(*result)

 

저작자표시 비영리 변경금지 (새창열림)

'Deprecated' 카테고리의 다른 글

[Baekjoon Online Judge] 백준 1932번 정수 삼각형(C++, Python)  (0) 2020.04.12
[Baekjoon Online Judge] 백준 2579번 계단 오르기(C++, Python)  (0) 2020.04.12
[Baekjoon Online Judge] 백준 2580번 스도쿠(C++, Python)  (0) 2020.04.10
[Baekjoon Online Judge] 백준 2585번 경비행기(C++, Python)  (0) 2020.04.09
[Baekjoon Online Judge] 백준 1712번 손익분기점(C++, Python)  (0) 2020.04.07
    'Deprecated' 카테고리의 다른 글
    • [Baekjoon Online Judge] 백준 1932번 정수 삼각형(C++, Python)
    • [Baekjoon Online Judge] 백준 2579번 계단 오르기(C++, Python)
    • [Baekjoon Online Judge] 백준 2580번 스도쿠(C++, Python)
    • [Baekjoon Online Judge] 백준 2585번 경비행기(C++, Python)
    HelloMinchan
    HelloMinchan
    Though you should not fear failure, You should do your very best to avoid it.

    티스토리툴바