- 선형탐색을 진행할 경우 O(N*M) 이므로 약 10,000,000,000 는 시간초과에 걸릴 것 같습니다.
- O(NlogN) 정렬 + O(M*logN) 이분탐색 으로 해결했습니다.
2. 주의사항
- 조건으로 인한 시간초과
3. 나의코드
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
int Narr[100000];
int N, M;
bool existnum(int target) {
int ep = N - 1;
int sp = 0;
int mid;
while (sp<=ep) {
mid = (sp + ep) / 2;
if (Narr[mid] == target) { return true; }
else if (Narr[mid] < target) {
sp = mid + 1;
}
else if (Narr[mid] > target) {
ep = mid - 1;
}
}
return false;
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin >> N;
for (int i = 0; i < N; i++) {
cin >> Narr[i];
}
sort(Narr, Narr+N); //이분탐색을 위한 정렬
cin >> M;
int target;
for (int i = 0; i < M; i++) {
cin >> target;
cout << existnum(target)<<"\n";
}
return 0;
}
#include<iostream>
#include<vector>
#include<string>
using namespace std;
int N, M;
vector<long long> arr;
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
cin >> N >> M;
long long tt;
for (int i = 0; i < N; i++) {
cin >> tt;
arr.push_back(tt);
}
int tmpsum = arr[0];
int resultcount = 0;
int sp = 0;
int ep = 0;
while (1) {
if (tmpsum == M) {
resultcount++;
tmpsum -= arr[sp];
sp++;
ep++;
if (ep == N) break;
tmpsum += arr[ep];
}
else if (tmpsum < M) {
ep++;
if (ep == N) break;
tmpsum += arr[ep];
}
else if (tmpsum > M) {
tmpsum -= arr[sp];
sp++;
}
}
cout << resultcount;
return 0;
}
#include<bits/stdc++.h>
using namespace std;
long long n, m,tmp;
vector<long long> commitarr;
long long resulttime=1e18;
void inputs() {
cin >> n >> m; //n개의 심사대 , m 명의 친구들
for (int i = 0; i < n; i++) {
cin >> tmp; commitarr.push_back(tmp);
}
}
void findtime(long long l, long long h)
{
if (l > h) return;
long long mid = (l + h) / 2;
long long tmpsum = 0;
for (int i = 0; i < n; i++) {
tmpsum += (mid / commitarr[i]); //시간동안 각각의 심사대에서 심사가능인원
}
if (tmpsum >= m) {
if (resulttime > mid) { resulttime = mid; } //더 적은시간으로 가능하면 갱신
findtime(l, mid - 1);
}
else findtime(mid + 1, h);
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
inputs();
sort(commitarr.begin(), commitarr.end());
long long lowtime = 1; long long hightime = commitarr[n - 1] * m;
//가장 오래걸리는 심사대에서 모두 받을 경우가 최대
findtime(lowtime, hightime);
cout << resulttime;
return 0;
}
- 이분 탐색을 통해 그것을 탐색해가면서 mid의 값이 아이들에게 조건에 맞게 나누어 줄 수 있는지 확인.
- 나누어 줄 수 있으면 더 작은 질투심을 유발할 수 있는 값이 있는지 mid보다 작은 쪽을 탐색.
- 아니라면 mid보다 큰 쪽을 탐색.
- 최소값을 출력하여 주었습니다.
2. 주의사항
- 없음.
3. 나의코드
#include<bits/stdc++.h>
using namespace std;
long long n, m;
long long numarr[300001];
long long result = 1e18;
bool canspread(long long mid) {
long long num = 0;
for (int i = 0; i < m; i++) {
num += numarr[i] / mid;
if (numarr[i] % mid) num++;
}
return n >= num;
}
int main() {
cin >> n >> m;
long long left = 1; long long right = 0;
for (int i = 0; i < m; i++) {
cin >> numarr[i];
if (right < numarr[i]) right = numarr[i];
}
while (left <= right) {
long long mid = (left + right) / 2;
if (canspread(mid)) {
if (result > mid) result = mid;
right = mid - 1;
}
else left = mid + 1;
}
cout << result << "\n";
return 0;
}