Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

11-oesnuj #38

Merged
merged 7 commits into from
Jul 24, 2024
Merged

11-oesnuj #38

merged 7 commits into from
Jul 24, 2024

Conversation

oesnuj
Copy link
Member

@oesnuj oesnuj commented Jul 18, 2024

πŸ”— 문제 링크

λ°±μ€€ | λžœμ„  자λ₯΄κΈ°

βœ”οΈ μ†Œμš”λœ μ‹œκ°„

1μ‹œκ°„

✨ μˆ˜λ„ μ½”λ“œ

문제의 핡심 : "k개의 λžœμ„ μ„ νŠΉμ • 길이둜 λžœμ„ μ„ 자λ₯Όλ•Œ n개 μ΄μƒμ˜ λ™μΌν•œ 길이의 λžœμ„ μ„ λ§Œλ“€ 수 μžˆλŠ”κ°€?"λ₯Ό νŒλ‹¨ν•˜λŠ” 것
μœ„ 쑰건을 λ§Œμ‘±ν•˜λŠ” κ°€μž₯ μ΅œλŒ€ λžœμ„  길이λ₯Ό κ΅¬ν•΄μ•Όν•©λ‹ˆλ‹€.

μ •λ‹΅λ₯ μ΄ 쑰금 μ΄μƒν•œ? 문제이긴 ν•œλ° μ•„λž˜ νƒμƒ‰λ²•λ§Œ μ œλŒ€λ‘œ μ΄ν•΄ν•˜λ©΄ 정말 μ‰½κ²Œ ν’€ 수 μžˆμ„ κ²λ‹ˆλ‹€.

πŸ‘€ 이뢄 탐색, λ§€κ°œλ³€μˆ˜ 탐색

이뢄탐색과 λ§€κ°œλ³€μˆ˜ 탐색이라고 λΆˆλ¦¬λŠ” 방식을 μ‚¬μš©ν•΄μ„œ ν•΄κ²°ν–ˆμŠ΅λ‹ˆλ‹€.

이뢄 탐색은 κ²°μ • 문제의 닡이 이뢄적일 λ•Œ μ‚¬μš©ν•  수 μžˆλŠ” νƒμƒ‰κΈ°λ²•μž…λ‹ˆλ‹€.
μ΄λ•Œ κ²°μ • λ¬Έμ œλŠ” 닡이 Yes or No인 문제λ₯Ό μ˜λ―Έν•˜λ©°, 보톡 ν•˜λ‚˜μ˜ λ§€κ°œλ³€μˆ˜λ₯Ό λ°›μ•„ T, Fλ₯Ό κ²°μ •ν•  수 μžˆλŠ” λ¬Έμ œμž…λ‹ˆλ‹€.

μ΄μ œλΆ€ν„° 이λ₯Ό μ‚¬μš©ν•œ μ˜ˆμ‹œλ₯Ό λ“€μ–΄ λ³΄κ² μŠ΅λ‹ˆλ‹€.
πŸ’‘1~10κΉŒμ§€μ˜ μ˜€λ¦„μ°¨μˆœμœΌλ‘œ μ •λ ¬λœ μΉ΄λ“œ λ”λ―Έμ—μ„œ 6을 μ°ΎλŠ” μƒν™©πŸ’‘μ΄λΌκ³  ν•˜κ² μŠ΅λ‹ˆλ‹€.
True, False둜만 λ‚˜μ˜€λŠ” κ²°μ • 문제λ₯Ό card[i] >= 6 으둜 μ„€μ •ν•˜λ©΄, iκ°€ 증가함에 따라 닡이 F, F, F, F, F, T, T, T, T, T둜 뢄포됨을 μ•Œ 수 μžˆμŠ΅λ‹ˆλ‹€.
μ΄λ•Œ μ°Ύκ³ μžν•˜λŠ” 값은 처음 κ²°μ • 문제의 닡이 Trueκ°€ λ˜λŠ” i κ°’μž…λ‹ˆλ‹€.

이뢄탐색을 μ μš©ν•˜λ©΄ κ²°μ •λ¬Έμ œμ˜ λ‹΅(F, T)이 λ°”λ€ŒλŠ” 경계λ₯Ό 찾을 수 μžˆμŠ΅λ‹ˆλ‹€.

이뢄 νƒμƒ‰μ˜ μ•„μ΄λ””μ–΄λŠ” 경계λ₯Ό ν¬ν•¨ν•˜λŠ” ꡬ간 [lo, hi]을 μž‘μ€ λ’€ κ΅¬κ°„μ˜ 길이λ₯Ό μ ˆλ°˜μ”© μ€„μ—¬λ‚˜κ°€λ©° lo, hi이 경계 지점에 μœ„μΉ˜ν•˜λ„λ‘ ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€. 이뢄 탐색이 λλ‚œ λ’€μ—” lo의 λ‹€μŒ 칸은 hi(즉, lo + 1 == hi)>이며 Check(lo) != Check(hi)μž…λ‹ˆλ‹€. μ΄λ•Œ Check(x)λŠ” κ²°μ • 문제의 parameterκ°€ x일 λ•Œ κ²°μ • 문제의 λ‹΅>을 μ˜λ―Έν•©λ‹ˆλ‹€.

μœ„ μ˜ˆμ‹œλ₯Ό μ„€λͺ…ν•œ μ‚¬μ§„μž…λ‹ˆλ‹€.

KakaoTalk_20240720_071108054

μ°Έκ³ ν•˜λ©΄ 쒋은 λΈ”λ‘œκ·Έ | 링크


λ‹€μ‹œ μˆ˜λ„ μ½”λ“œλ‘œ λŒμ•„μ™€μ„œ, μœ„ 방법을 λžœμ„  자λ₯΄κΈ° λ¬Έμ œμ— μ μš©μ‹œν‚΅λ‹ˆλ‹€.
(μ—¬κΈ°κΉŒμ§€ 보고 직접 풀어보셔도 쒋을 것 κ°™μ•„μš”.)

Note

  1. κ²°μ • 문제λ₯Ό μ •μ˜ν•˜κ³  κ²°μ •ν•¨μˆ˜ λ§Œλ“€κΈ°
    κ²°μ • 문제 : 길이 x둜 μž˜λžμ„λ•Œ N개 μ΄μƒμ˜ λžœμ„ μ΄ λ§Œλ“€μ–΄μ§€λŠ”κ°€?
    κ²°μ • ν•¨μˆ˜ : check ν•¨μˆ˜ λ§€κ°œλ³€μˆ˜λ‘œ lengthλ₯Ό λ°›μ•„ N개 μ΄μƒμœΌλ‘œ λ§Œλ“€ 수 μžˆλŠ”μ§€ μ•„λ‹Œμ§€λ₯Ό returnν•œλ‹€.

length둜 λžœμ„ λ“€μ„ μž˜λžμ„λ•Œ λ‚˜μ˜€λŠ” 쑰각의 갯수λ₯Ό κ΅¬ν•©λ‹ˆλ‹€.
이 κ°―μˆ˜κ°€ n보닀 ν¬κ±°λ‚˜ κ°™μœΌλ©΄ trueλ₯Ό 리턴, μ•„λ‹ˆλ©΄ falseλ₯Ό 리턴

bool check(vector <int>& v, int n, long long length) {
    int cnt = 0;
    for (const auto& i : v) {
        cnt += i / length;
    }
    return cnt >= n;
}

Note

2. μž…λ ₯ 받은 λ‚˜λ¬΄κΈΈμ΄μ™€ ν•„μš”κ°œμˆ˜ N을 μ΄μš©ν•΄ 이뢄탐색 적용

λ¨Όμ € lo, hiκ°€ μ •λ‹΅μ˜ λ²”μœ„λ₯Ό λ‚˜νƒ€λ‚Ό 수 μžˆλ„λ‘ μ„€μ •ν•΄μ•Όν•©λ‹ˆλ‹€.
lo = 1, hi = κ°€λŠ₯ν•œ μ΅œλŒ€κΈΈμ΄ +1둜 λ‘‘λ‹ˆλ‹€. => long long lo = 1, hi = 2147483648;둜 λ‘μ—ˆμŠ΅λ‹ˆλ‹€.
hiλ₯Ό μž…λ ₯받은 λžœμ„ κΈΈμ΄μ˜ μ΅œλŒ€κ°’μœΌλ‘œ μ„€μ •ν•˜λ©΄ μ‘°κΈˆμ€ 더 효율적일 κ²λ‹ˆλ‹€.

mid = (lo + hi) / 2
λ§Œμ•½ check(mid)κ°€ True 라면 lo = mid둜 μ„€μ •ν•©λ‹ˆλ‹€. ( check(mid) == check(lo) 인 경우)
λ°˜λŒ€λ‘œ check(mid) False 라면 hi = mid둜 μ„€μ •ν•©λ‹ˆλ‹€. ( check(mid) == check(hi) 인 경우)
이λ₯Ό while(lo+1 < hi)λ™μ•ˆ λ°˜λ³΅ν•©λ‹ˆλ‹€.

check(mid)κ°€ True라면 ν˜„μž¬ mid μ™Όμͺ½μ€ λ‹€ True 이기에 경계λ₯Ό μ°ΎκΈ°μœ„ν•΄μ„œλŠ” 더이상 λ³Ό ν•„μš”μ—†κΈ°μ— lo =mid둜 ν•©λ‹ˆλ‹€.
λ°˜λŒ€λ‘œ False라면 ν˜„μž¬ mid의 였λ₯Έμͺ½μ€ λ‹€ False이기에 λ³Ό ν•„μš” μ—†μŠ΅λ‹ˆλ‹€.

λ‚˜λ¬΄λ₯Ό 짧게 자λ₯Ό 수둝 많이 μ‘°κ°λ‚˜κ³ , 길게 짜λ₯Ό 수둝 적게 μ‘°κ°λ‚˜κΈ° λ•Œλ¬Έμ— κ²°μ • λ¬Έμ œμ— λŒ€ν•œ λ‹΅ 뢄포가 T, ... , T, F, ... , Fκ°€ λ©λ‹ˆλ‹€.
λ”°λΌμ„œ 반볡문이 λλ‚¬μ„λ•Œ loκ°€ λ°”λ‘œ N개 μ΄μƒμœΌλ‘œ λ§Œλ“œλŠ” κ°€μž₯ κΈ΄ λžœμ„ κΈΈμ΄κ°€ λ©λ‹ˆλ‹€.

int binary_serach(vector <int>& v, int n) {
   long long lo = 1, hi = 2147483648; //자λ₯Ό 수 μžˆλŠ” λžœμ„ μ˜ λ²”μœ„
   while (lo + 1 < hi) {
       long long mid = (lo + hi) / 2;
       if (check(v, n, mid)) lo = mid;
       else hi = mid;
   }
   return lo;
}

β›”μ£Όμ˜ν•  점

  1. κ°€λŠ₯ν•œ λžœμ„  길이의 μ΅œλŒ“κ°’μ΄ 2의 32제곱 - 1 μ΄λ―€λ‘œ 이뢄탐색 μ‹œμ— intν˜•μœΌλ‘œ midλ₯Ό μ„ μ–Έν•˜λ©΄ μ˜€λ²„ν”Œλ‘œμš°κ°€ λ°œμƒ
    => long long μžλ£Œν˜•μœΌλ‘œ ν•΄κ²°

πŸ“ƒ 전체 μ½”λ“œ

#include <iostream>
#include <vector>
using namespace std;

bool check(vector <int>& v, int n, long long length);
int binary_serach(vector <int>& v, int n);

int main() {
    int k, n;
    cin >> k >> n;
    vector <int> v(k);
    for (auto& i : v) {
        cin >> i;
    }
    cout << binary_serach(v, n);
    return 0;
}

bool check(vector <int>& v, int n, long long length) {
    int cnt = 0;
    for (const auto& i : v) {
        cnt += i / length;
    }
    return cnt >= n;
}

int binary_serach(vector <int>& v, int n) {
    long long lo = 1, hi = 2147483648; //자λ₯Ό 수 μžˆλŠ” λžœμ„ μ˜ λ²”μœ„
    while (lo + 1 < hi) {
        long long mid = (lo + hi) / 2;
        if (check(v, n, mid)) lo = mid;
        else hi = mid;
    }
    return lo;
}

πŸ“š μƒˆλ‘­κ²Œ μ•Œκ²Œλœ λ‚΄μš©

이뢄 탐색 ν™œμš©λ²•μ— λŒ€ν•΄μ„œ μ œλŒ€λ‘œ λ°°μ›Œκ°‘λ‹ˆλ‹€. λ²½ ν•˜λ‚˜ ν—ˆλ¬Έ λŠλ‚Œμ΄λ„€μš”...

  1. 이뢄 탐색(맀개 λ³€μˆ˜ 탐색)으둜 쑰건의 경계값을 쉽고 λΉ λ₯΄κ²Œ κ΅¬ν•˜κΈ°
  • check[lo]와 check[hi]κ°€ λ°˜λ“œμ‹œ λ‹¬λΌμ•Όν•©λ‹ˆλ‹€.
  • lo, hiλŠ” 항상 μ •λ‹΅μ˜ λ²”μœ„λ₯Ό λ‚˜νƒ€λ‚Ό 수 μžˆλ„λ‘ ν•΄μ•Όν•©λ‹ˆλ‹€.
  1. lower_bound, upper_bound
    C++의 ν—€λ”μ—λŠ” μ΄λŸ¬ν•œ 이뢄 탐색 λ‘œμ§μ„ ν™œμš©ν•˜μ—¬ λ§Œλ“  ν•¨μˆ˜λ“€μ΄ μžˆμŠ΅λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄, lower_bound와 upper_bound ν•¨μˆ˜λŠ” λ°°μ—΄μ—μ„œ νŠΉμ • κ°’ μ΄μƒμ˜ μ›μ†Œκ°€ 처음 λ“±μž₯ν•˜λŠ” μœ„μΉ˜λ₯Ό μ•Œλ €μ€λ‹ˆλ‹€. ν•„μš”ν•˜λ‹€λ©΄ 라이브러리λ₯Ό μ‚¬μš©ν•΄μ„œλ„ ν’€μ–΄λ΄μ•Όκ² μŠ΅λ‹ˆλ‹€.

Copy link
Collaborator

@suhyun113 suhyun113 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

와,,,μ—„μ²­ κΌΌκΌΌν•˜κ²Œ PR μž‘μ„±ν•΄μ£Όμ…”μ„œ κ°μ‚¬ν•©λ‹ˆλ‹€! 이뢄 탐색에 λŒ€ν•΄ 거의 λͺ°λžλŠ”데 곡뢀가 λ˜μ—ˆμŠ΅λ‹ˆλ‹€γ… μ€€μ„œλ‹˜κ»˜μ„œ μ˜ˆμ‹œλ‘œ μ•Œλ €μ£Όμ‹  상황은 사진을 보고 μ–΄λ–»κ²Œ 이해가 λ˜μ—ˆμŠ΅λ‹ˆλ‹€. 그런데 막상 μ½”λ“œλ₯Ό λ³΄λ‹ˆ..μ’€ μ–΄λ ΅λ”λΌκ΅¬μš”γ… γ…  κ²°μ • ν•¨μˆ˜μ™€ 이뢄 탐색 ν•¨μˆ˜λ₯Ό λ‚˜λˆ„μ–΄ κ΅¬ν˜„ν•΄μ£Όμ…”μ„œ 가독성이 μ’‹λ”λΌκ΅¬μš”! κ·ΈλŸΌμ—λ„ μ™œ μ΄λŸ¬ν•œ 둜직이 된 건지 μ΄ν•΄ν•˜κΈ° μ–΄λ €μ›Œ μ„€λͺ…을 μ—¬λŸ¬ 번 μ½μ–΄λ΄€μŠ΅λ‹ˆλ‹€. 계속 λ³΄λ‹ˆ 특히 이뢄 탐색 뢀뢄이 μ΄μ „μ˜ μ˜ˆμ‹œμ—μ„œ λ³Έ κ²ƒμ²˜λŸΌ 계산 ν•˜λŠ” 뢀뢄이 κ°™μ•„ 이해가 잘 된 것 κ°™μŠ΅λ‹ˆλ‹€. μ½”λ“œκ°€ κ°„κ²°ν•˜κ³  λͺ…ν™•ν•˜μ—¬ μ’‹μ•˜μŠ΅λ‹ˆλ‹€!
이뢄 탐색에 λŒ€ν•΄ 잘 λͺ°λΌμ„œ μ™œ 이뢄 탐색이 νš¨μœ¨μ μΈμ§€ κΆκΈˆν•΄ μ’€ μ°Ύμ•„λ³΄κ²Œ λ˜μ—ˆλŠ”λ°, 졜적의 값을 μ°ΎλŠ” 문제이기 λ•Œλ¬Έμ΄λΌλŠ” 것을 μ•Œκ²Œλ˜μ—ˆμŠ΅λ‹ˆλ‹€. 이 문제 μ—­μ‹œ 주어진 λžœμ„  길이듀을 μ‚¬μš©ν•΄ μ›ν•˜λŠ” 개수 μ΄μƒμ˜ λžœμ„ μ„ λ§Œλ“€ 수 μžˆλŠ” μ΅œλŒ€ 길이λ₯Ό μ°ΎλŠ” 문제이기 λ•Œλ¬Έμ— μ΅œμ κ°’μ„ λΉ λ₯΄κ²Œ 찾을 수 μžˆμŠ΅λ‹ˆλ‹€.
그리고 이 문제λ₯Ό κ²°μ • 문제둜 λ³€ν™˜ν–ˆμ„ λ•Œ, μ€€μ„œλ‹˜κ»˜μ„œ λ§ν•˜μ‹  **"ν˜„μž¬ 길이둜 λžœμ„ μ„ 자λ₯Ό λ•Œ, n개 μ΄μƒμ˜ λžœμ„ μ„ λ§Œλ“€ 수 μžˆλŠ”κ°€?"**둜 μ •μ˜ν•  수 μžˆλ‹€λŠ” 것을 μ•Œκ²Œλ˜μ—ˆμŠ΅λ‹ˆλ‹€.
첨뢀해주신 λ§ν¬μ—μ„œλ„ 이뢄 νƒμƒ‰μ˜ μ •μ˜μ— λŒ€ν•΄μ„œ μ•Œ 수 μžˆμ—ˆμŠ΅λ‹ˆλ‹€! μ’€ 더 이뢄 탐색에 λŒ€ν•΄ 곡뢀해봐야 κ² μ–΄μš”! 이번 PR도 μˆ˜κ³ ν•˜μ…¨μŠ΅λ‹ˆλ‹€!

Copy link
Collaborator

@pu2rile pu2rile left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ν—ˆμ–΄μ–΄ 이 μ •μ„±μŠ€λŸ¬μš΄ pr... 🀩 μ€€μ„œλ‹˜μ΄ μ„€λͺ…ν•΄ μ£Όμ‹  λ‘œμ§μ„ 읽어 λ³΄λ‹ˆ λ­”κ°€ μ΅μˆ™ν•œ 뢀뢄이 μžˆμ—ˆλŠ”λ°... μ •λ ¬ μ•Œκ³ λ¦¬μ¦˜μΈ 퀡 μ •λ ¬κ³Ό μœ μ‚¬ν•˜λ„€μš”!! 퀡 정렬은 λΆ„ν•  정볡 방식을 μ‚¬μš©ν•΄μ„œ 배열을 μ •λ ¬ν•˜μ§€μš”... 처음 μ΅œμ’… μ½”λ“œλ§Œ 봀을 땐 이해가 μ–΄λ €μ› λŠ”λ° 정말 μ„Έμ„Έν•˜κ²Œ 잘 μ„€λͺ…ν•΄ μ£Όμ…”μ„œ λ‹€μ‹œ λ³΄λ‹ˆ μ½”λ“œκ°€ μ½νž™λ‹ˆλ‹€!! 그리고 덕뢄에 c++μ—λŠ” 이뢄 탐색을 μœ„ν•œ λΌμ΄λΈŒλŸ¬λ¦¬κ°€ μžˆλ‹€λŠ” 것도 μ•Œμ•„κ°€μš”... pr λ„ˆλ¬΄ μˆ˜κ³ ν•˜μ…¨μŠ΅λ‹ˆλ‹€~~!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants