Algorithm
[BOJ] 2647 용액
도라프
2023. 5. 3. 19:34
https://www.acmicpc.net/problem/2467
[BOJ] 2467 용액
- 어떤 근을 찾는 문제가 아니라 비교값의 최소를 구하는 문제였기 때문에 투포인터를 사용하려고 했다. 그런데 하나 하나 다 비교한다면 시간 복잡도가 커지기 때문에 대소 비교하고 값 조정하는 이분 탐색의 틀을 사용하려는 시도를 했다.
- 대소를 어떻게 비교하고 어떻게 변수를 변화시켜줘야하는지 아이디어를 갖는 과정에서 이해가 안되는 부분이 많았다.
- 절대값을 비교하는 작업을 했는데, 이 과정에서 막히는 게 발생을 하였다. 큰 값을 지정해놓고 그 값보다 작다면 출력하는 정답 변수에 넣어주는 과정을 거쳤다.
고민 요소
- 초기 값을 ans에 넣어놓고 그 값보다 작은 절대값을 만나면 정답 변수에 넣어주려고 했는데, 맨처음 ans를 초기화 해줄 때 int ans = abs(sol[start] + sol[end]); 로 설정했을 때 출력이 이상한 값이 되어서 검색을 통해 int의 가장 큰 값을 넣어주게 되었다.
- 아직도 이유는 모르겠어서 같이 논의해보면 좋을 것 같다
- end와 start 값을 바꾸는 식을 내는 것이 어려웠는데 문제의 오름차순으로 입력부분을 보지 못해서 초반에 갈피를 못잡았었다. 그런데 만약 더하는 값이 음수일 경우에는 더 큰 값을 더해줬을 때 0이랑 가까운지 확인하기 위해 start를 1 증가시키고, 반대의 경우에는 end를 1 감소시키는 방식이라는 것을 깨달았다.
문제 풀이 코드
#include <iostream>
#include <algorithm>
#define MAX 100000
using namespace std;
int sol[MAX];
int main() {
ios::sync_with_stdio(false);
cout.tie(0);
cin.tie(0);
int n;
cin >> n;
for(int i = 0; i< n; i++){
cin >> sol[i];
}
// for(int i = 0; i< n; i++){
// cout << sol[i] <<" ";
// }
int start = 0;
int end = n-1;
int ans = 2147483647;
int answer[2];
while(start < end){
int sum = abs(sol[start] + sol[end]);
int num = sol[start] + sol[end];
if(abs(sol[start] + sol[end]) < ans){
ans = sum;
answer[0] = sol[start];
answer[1] = sol[end];
if(ans == 0) break;
}
if(num > 0){
end --;
}else{
start ++;
}
}
cout << answer[0] <<" "<<answer[1];
return 0;
}