[BOJ]2467-溶液
これは,並べ替え後の配列に2つの値を加え,0に最も近い2つの値を探す問題である.
解題ポリシー
答えを出す.
初めてこの問題をするときは二重ポインタを使いました.
始点と終点を指定した後、2つの値が0より大きい場合は終点を減らし、0より小さい場合は始点を増やします.
この方法で,O(n)は十分に解ける.
説明する.
もう一つの解釈は二分探索を用いることができる.
0に最も近い値を探す問題なので、現在の値の負の値に最も近い値を見つければいいのです.
たとえば、現在のブラウズ値が8の場合、0に最も近い値は-8に最も近い値でなければなりません.
したがって、現在検索されている値を負に変換する値は、指定された配列に見つかればよい.
このプロシージャを配列の最初の値から最後の値に繰り返すとよい.
コード#コード#
https://www.acmicpc.net/problem/2467
解題ポリシー
答えを出す.
初めてこの問題をするときは二重ポインタを使いました.
始点と終点を指定した後、2つの値が0より大きい場合は終点を減らし、0より小さい場合は始点を増やします.
この方法で,O(n)は十分に解ける.
説明する.
もう一つの解釈は二分探索を用いることができる.
0に最も近い値を探す問題なので、現在の値の負の値に最も近い値を見つければいいのです.
たとえば、現在のブラウズ値が8の場合、0に最も近い値は-8に最も近い値でなければなりません.
したがって、現在検索されている値を負に変換する値は、指定された配列に見つかればよい.
このプロシージャを配列の最初の値から最後の値に繰り返すとよい.
コード#コード#
#include<iostream>
#include<vector>
#include<algorithm>
#include<math.h>
using namespace std;
int n;
vector<int> v;
int target = 2000000000;
void f1_tp(){
int s = 0;
int e = v.size()-1;
int ans[2] = {-1,-1};
while(s < e){
int sum = v[s] + v[e];
if(abs(sum) < target){
ans[0] = v[s];
ans[1] = v[e];
target = abs(sum);
}
if(sum >= 0){
e--;
}else{
s++;
}
}
cout << ans[0] << " " << ans[1] << "\n";
}
void f2_bs(){
int ans[2] = {-1,-1};
for(int i=0;i<v.size();i++){
int idx = lower_bound(v.begin(), v.end(), -v[i]) - v.begin();
for(int j = idx-1;j<=idx;j++){ // idx-1 vs idx
if(j == i || j<0 || j>=n)
continue;
if(v[j] + v[i] == 0){
ans[0] = v[j];
ans[1] = v[i];
if(ans[0] > ans[1])
swap(ans[0], ans[1]);
cout << ans[0] << " " << ans[1] << "\n";
return;
}else{
if(target <= abs(v[j] + v[i]))
continue;
ans[0] = v[j];
ans[1] = v[i];
target = abs(v[j] + v[i]);
}
}
}
if(ans[0] > ans[1])
swap(ans[0], ans[1]);
cout << ans[0] << " " << ans[1] << "\n";
}
int main(){
cin >> n;
for(int i=0;i<n;i++){
int tmp;
cin >> tmp;
v.push_back(tmp);
}
//f1_tp(); // two pointer
f2_bs(); // binary search
}
ソースhttps://www.acmicpc.net/problem/2467
Reference
この問題について([BOJ]2467-溶液), 我々は、より多くの情報をここで見つけました https://velog.io/@kms9887/BOJ-2467-용액テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol