#include <iostream>
using namespace std;
int n, q;
int arr[500001] = { 0, };
int qarr[500001] = { 0, };
int binarysearch(int v, int s, int e) { // recursion
//1.base condition
if (s > e)
return -1;
//2.divide
int m = (s + e) / 2;
if (v == arr[m]) return m;
else if (v > arr[m]) return binarysearch(v, m + 1, e);
else return binarysearch(v, s, m - 1);
}
int binarysearch2(int v, int s, int e) { // while
int start_val = s;
int end_val = e;
while (start_val <= end_val) {
int m = (start_val + end_val) / 2;
if (v == arr[m]) return m;
else if (v > arr[m]) start_val = m + 1;
else end_val = m - 1;
}
return -1;
}
int main() {
cin >> n;
for (int i = 0; i < n; i++)
cin >> arr[i];
cin >> q;
for (int i = 0; i < q; i++)
cin >> qarr[i];
for (int i = 0; i < q; i++) {
int val = binarysearch(qarr[i],0,n-1);
cout << val;
if (i != (q - 1))
cout << ' ';
}
cout << endl;
return 0;
}
2. 이분탐색에서의 조건은 휴게소 간격들 사이 해당 거리(mid) 만큼 지정했을 때, 배치 가능한 갯수
문제풀이
주석을 자세하게 적어 놓아기 때문에 생략
정답 코드입니다.
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int n, m, l;
vector <int> vec;
bool cmp(int& a, int& b) { // 없어도 되지만 간만에 짜보고 싶었어요ㅋㅋ
if (a < b)
return true;
return false;
}
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
cin >> n >> m >> l;
int temp;
vec.push_back(0), vec.push_back(l); //시작점과 끝점 추가 + 이미 휴게소가 있는 곳에 휴게소를 또 세울 수 없고, 고속도로의 끝에도 휴게소를 세울 수 없다. 라는 조건 때문에
for (int i = 0; i < n; i++) {
cin >> temp;
vec.push_back(temp);
}
sort(vec.begin(), vec.end(), cmp);
int low = 0, high = l;
int mid, result = 0;
while (low <= high) {
mid = (low + high) / 2;
int val = 0; // 휴게소 사이에 배치 될 수있는 휴게소의 갯수
for (int i = 1; i < vec.size(); i++) {
int dist = vec[i] - vec[i - 1]; // 휴게소 a와 b 사이에 간격
val += (dist / mid); // 휴게소 간격 / 현재 길이
if (dist%mid == 0) //휴게소가 이미 있는 위치라면
val--; // 갯수를 하나 감소 시켜주어야지.
}
if (val > m) // 배치할 수 있는 휴게소가 m개 보다 많으면
low = mid + 1; // 길이를 늘려주어 m개가 배치 되게끔 만들어주고
else {// 배치될 휴게소가 m개보다 작거나 같을 때
high = mid - 1;// 길이(mid)가 더 작아질 수 있을지 확인해야지
result = mid; //결과값을 갱신해주기
}
}
cout << result << endl;
return 0;
}
4. 10,000*10,000 = 100,000,000 X 4Byte = 대략 400Mb... 즉, dp방식도 불가능
5. 이분탐색을 통해서 방문하는 범위를 줄여볼까? 생각하게 됨
문제풀이
1. 결과값은 다리의 비용중에 하나이다.2. 최소 비용(0), 최대비용(다리 비용중 최대값)을 low, high값으로 지정하고 mid값일때, 이동가능한지 확인3. 간단한 bfs를 통해서 이동이 가능한지 확인 4. 이동이 불가하면 high값을 낮춰주고, 이동이 가능하면 low값을 올려주며 진행
이분탐색 + bfs로 해결하는 문제입니다. 아래는 정답코드입니다.
#include <iostream>
#include <vector>
#include <queue>
#include <cstring>
using namespace std;
int n, m;
int a, b, c;
vector <pair<int, int>> vec[10001];
bool visited[10001];
int s, e;
int bfs(int cost) {
queue <int> que;
que.push(s);
visited[s] = 1;
while (!que.empty()) {
int cur = que.front();
que.pop();
if (cur == e)
return true;
for (int i = 0; i < vec[cur].size(); i++) {
int ncur = vec[cur][i].first;
int ncos = vec[cur][i].second;
if (!visited[ncur] && ncos >= cost) {
visited[ncur] = 1;
que.push(ncur);
}
}
}
return false;
}
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
cin >> n >> m;
int from, to, cost;
int maxcost = 0;
for (int i = 0; i < m; i++) {
cin >> from >> to >> cost;
vec[from].push_back(make_pair(to, cost));
vec[to].push_back(make_pair(from, cost));
if (cost > maxcost)
maxcost = cost;
}
cin >> s >> e;
int low = 0, high = maxcost;
while (low <= high) {
memset(visited, 0, sizeof(visited));
int mid = (low + high)/2;
if (bfs(mid)) {
low = mid + 1;
}
else {
high = mid - 1;
}
}
cout << high << endl;
return 0;
}