https://www.acmicpc.net/problem/2467
[필자 사고]
정렬되어 있다. 이 키워드를 통해 이 문제는 이분탐색 아니면 투포인터이지 않을까?? 와 같은 사고를 했다.
문제를 읽어보니 부르스트 알고리즘을 적용하면 시간내에 못 풀게 되어 있다.
역시나 투포인터 알고리즘을 이용해야 된느 문제이다.
O(nlogn) 시간복잡도로 충분히 시간 내에 풀 수 있다.
필자가 실수 했던 부분은 초기화 부분에 있었다.
1. 먼저 long 으로 해야된다.
2. arr[left]+ arr[right] 등의 숫자들을 미리 담아나야된다.
이 부분만 신경쓰면 쉽게 해결할 수 있따.
[코드 해설]
- Input 함수
- N개의 정수를 입력받는다.
- 입력된 정수들을 저장할 arr 벡터를 초기화하고, 순서대로 값을 저장한다.
- Two_Pointer 함수
- 두 포인터(left와 right)를 사용하여 배열의 양 끝에서 시작한다.
- 각 반복마다 arr[left]와 arr[right]의 합을 계산하고, 절댓값이 최소가 되는 경우를 찾는다.
- 만약 현재 합(nowSum)이 음수라면, left를 오른쪽으로 이동하여 값을 증가시킨다.
- 반대로 nowSum이 양수라면, right를 왼쪽으로 이동하여 값을 감소시킨다.
- 이 과정을 통해 두 값(leftValue, rightValue)의 합이 0에 가장 가까운 조합을 찾는다.
- GameStart 함수
- Two_Pointer 함수를 호출하여 최소 절댓값 합을 구한다.
- 구한 결과(leftValue와 rightValue)를 출력한다.
- main 함수
- Input 함수를 호출하여 데이터를 입력받는다.
- GameStart 함수로 로직을 실행하고 결과를 출력한다.
[소스 코드]
#include <iostream>
#include <vector>
using namespace std;
int N;
vector<long> arr;
long resultSum = 987654321;
long leftValue=0, rightValue=0;
void Input() {
cin >> N;
arr.resize(N);
for (int i = 0; i < N; i++) {
cin >> arr[i];
}
}
void Two_Pointer() {
int left = 0;
int right = N - 1;
leftValue = arr[left];
rightValue = arr[right];
resultSum = abs(arr[left] + arr[right]);
while (left < right) {
long nowSum = arr[left] + arr[right];
if (resultSum > abs(nowSum)) {
resultSum = abs(nowSum);
leftValue = arr[left];
rightValue = arr[right];
}
if (nowSum < 0)left++;
else right--;
//음수면 왼쪽을 오른쪽으로
//양수면 right 을 감소
}
}
void GameStart() {
Two_Pointer();
cout << leftValue << " " << rightValue;
}
int main(void) {
Input();
GameStart();
}
'백준 > 투포인터' 카테고리의 다른 글
백준 1806 c++ "부분합" -PlusUltraCode- (0) | 2024.12.25 |
---|---|
백준 12891 c++ "DNA 비밀번호" -PlusUltraCode- (0) | 2024.08.14 |
백준 1253 c++ "좋다" -PlusUltraCode- (0) | 2024.08.13 |
백준 1940 c++ "주몽" -PlusUltraCode- (0) | 2024.08.13 |