1/*
2 * ํ์ ์๊ณ ๋ฆฌ์ฆ (Searching Algorithms)
3 * Linear Search, Binary Search, Parametric Search
4 *
5 * ๋ค์ํ ํ์ ๊ธฐ๋ฒ๊ณผ ์ด๋ถ ํ์ ์์ฉ์
๋๋ค.
6 */
7
8#include <stdio.h>
9#include <stdlib.h>
10#include <stdbool.h>
11
12/* =============================================================================
13 * 1. ์ ํ ํ์ - O(n)
14 * ============================================================================= */
15
16int linear_search(int arr[], int n, int target) {
17 for (int i = 0; i < n; i++) {
18 if (arr[i] == target)
19 return i;
20 }
21 return -1;
22}
23
24/* =============================================================================
25 * 2. ์ด๋ถ ํ์ - O(log n)
26 * ============================================================================= */
27
28int binary_search(int arr[], int n, int target) {
29 int left = 0, right = n - 1;
30
31 while (left <= right) {
32 int mid = left + (right - left) / 2;
33
34 if (arr[mid] == target)
35 return mid;
36 else if (arr[mid] < target)
37 left = mid + 1;
38 else
39 right = mid - 1;
40 }
41
42 return -1;
43}
44
45/* ์ฌ๊ท ๋ฒ์ */
46int binary_search_recursive(int arr[], int left, int right, int target) {
47 if (left > right)
48 return -1;
49
50 int mid = left + (right - left) / 2;
51
52 if (arr[mid] == target)
53 return mid;
54 else if (arr[mid] < target)
55 return binary_search_recursive(arr, mid + 1, right, target);
56 else
57 return binary_search_recursive(arr, left, mid - 1, target);
58}
59
60/* =============================================================================
61 * 3. Lower Bound / Upper Bound
62 * ============================================================================= */
63
64/* target ์ด์์ธ ์ฒซ ๋ฒ์งธ ์์น */
65int lower_bound(int arr[], int n, int target) {
66 int left = 0, right = n;
67
68 while (left < right) {
69 int mid = left + (right - left) / 2;
70 if (arr[mid] < target)
71 left = mid + 1;
72 else
73 right = mid;
74 }
75
76 return left;
77}
78
79/* target ์ด๊ณผ์ธ ์ฒซ ๋ฒ์งธ ์์น */
80int upper_bound(int arr[], int n, int target) {
81 int left = 0, right = n;
82
83 while (left < right) {
84 int mid = left + (right - left) / 2;
85 if (arr[mid] <= target)
86 left = mid + 1;
87 else
88 right = mid;
89 }
90
91 return left;
92}
93
94/* target์ ๊ฐ์ */
95int count_occurrences(int arr[], int n, int target) {
96 return upper_bound(arr, n, target) - lower_bound(arr, n, target);
97}
98
99/* =============================================================================
100 * 4. ์ฝ์
์์น ์ฐพ๊ธฐ
101 * ============================================================================= */
102
103int search_insert(int arr[], int n, int target) {
104 int left = 0, right = n;
105
106 while (left < right) {
107 int mid = left + (right - left) / 2;
108 if (arr[mid] < target)
109 left = mid + 1;
110 else
111 right = mid;
112 }
113
114 return left;
115}
116
117/* =============================================================================
118 * 5. ํ์ ์ ๋ ฌ ๋ฐฐ์ด ํ์
119 * ============================================================================= */
120
121int search_rotated(int arr[], int n, int target) {
122 int left = 0, right = n - 1;
123
124 while (left <= right) {
125 int mid = left + (right - left) / 2;
126
127 if (arr[mid] == target)
128 return mid;
129
130 /* ์ผ์ชฝ์ด ์ ๋ ฌ๋จ */
131 if (arr[left] <= arr[mid]) {
132 if (arr[left] <= target && target < arr[mid])
133 right = mid - 1;
134 else
135 left = mid + 1;
136 }
137 /* ์ค๋ฅธ์ชฝ์ด ์ ๋ ฌ๋จ */
138 else {
139 if (arr[mid] < target && target <= arr[right])
140 left = mid + 1;
141 else
142 right = mid - 1;
143 }
144 }
145
146 return -1;
147}
148
149/* ํ์ ๋ฐฐ์ด์์ ์ต์๊ฐ */
150int find_min_rotated(int arr[], int n) {
151 int left = 0, right = n - 1;
152
153 while (left < right) {
154 int mid = left + (right - left) / 2;
155
156 if (arr[mid] > arr[right])
157 left = mid + 1;
158 else
159 right = mid;
160 }
161
162 return arr[left];
163}
164
165/* =============================================================================
166 * 6. ํ๋ผ๋ฉํธ๋ฆญ ์์น
167 * ============================================================================= */
168
169/* ๋ฐฐ์ด์ k๊ฐ๋ก ๋๋ ๋ ์ต๋ ํฉ์ ์ต์๊ฐ */
170bool can_split(int arr[], int n, int max_sum, int k) {
171 int count = 1;
172 int current_sum = 0;
173
174 for (int i = 0; i < n; i++) {
175 if (arr[i] > max_sum)
176 return false;
177
178 if (current_sum + arr[i] > max_sum) {
179 count++;
180 current_sum = arr[i];
181 } else {
182 current_sum += arr[i];
183 }
184 }
185
186 return count <= k;
187}
188
189int split_array_min_max(int arr[], int n, int k) {
190 int left = 0, right = 0;
191
192 for (int i = 0; i < n; i++) {
193 if (arr[i] > left) left = arr[i];
194 right += arr[i];
195 }
196
197 while (left < right) {
198 int mid = left + (right - left) / 2;
199
200 if (can_split(arr, n, mid, k))
201 right = mid;
202 else
203 left = mid + 1;
204 }
205
206 return left;
207}
208
209/* ๋๋ฌด ์๋ฅด๊ธฐ: ๋์ด H๋ก ์๋์ ๋ M ์ด์์ ๋๋ฌด๋ฅผ ์ป์ ์ ์๋ ์ต๋ H */
210long long cut_trees(int trees[], int n, long long target) {
211 long long left = 0, right = 0;
212
213 for (int i = 0; i < n; i++) {
214 if (trees[i] > right)
215 right = trees[i];
216 }
217
218 while (left < right) {
219 long long mid = left + (right - left + 1) / 2;
220 long long total = 0;
221
222 for (int i = 0; i < n; i++) {
223 if (trees[i] > mid)
224 total += trees[i] - mid;
225 }
226
227 if (total >= target)
228 left = mid;
229 else
230 right = mid - 1;
231 }
232
233 return left;
234}
235
236/* =============================================================================
237 * 7. ์ค์ ์ด๋ถ ํ์
238 * ============================================================================= */
239
240double sqrt_binary_search(double x) {
241 if (x < 0) return -1;
242 if (x < 1) {
243 double lo = x, hi = 1.0;
244 while (hi - lo > 1e-9) {
245 double mid = (lo + hi) / 2;
246 if (mid * mid < x)
247 lo = mid;
248 else
249 hi = mid;
250 }
251 return lo;
252 }
253
254 double lo = 1.0, hi = x;
255 while (hi - lo > 1e-9) {
256 double mid = (lo + hi) / 2;
257 if (mid * mid < x)
258 lo = mid;
259 else
260 hi = mid;
261 }
262 return lo;
263}
264
265/* =============================================================================
266 * 8. ํผํฌ ์ฐพ๊ธฐ
267 * ============================================================================= */
268
269int find_peak(int arr[], int n) {
270 int left = 0, right = n - 1;
271
272 while (left < right) {
273 int mid = left + (right - left) / 2;
274
275 if (arr[mid] < arr[mid + 1])
276 left = mid + 1;
277 else
278 right = mid;
279 }
280
281 return left;
282}
283
284/* =============================================================================
285 * ํ
์คํธ
286 * ============================================================================= */
287
288void print_array(int arr[], int n) {
289 printf("[");
290 for (int i = 0; i < n; i++) {
291 printf("%d", arr[i]);
292 if (i < n - 1) printf(", ");
293 }
294 printf("]");
295}
296
297int main(void) {
298 printf("============================================================\n");
299 printf("ํ์ ์๊ณ ๋ฆฌ์ฆ (Searching Algorithms) ์์ \n");
300 printf("============================================================\n");
301
302 /* 1. ์ด๋ถ ํ์ */
303 printf("\n[1] ์ด๋ถ ํ์\n");
304 int arr1[] = {1, 3, 5, 7, 9, 11, 13, 15};
305 printf(" ๋ฐฐ์ด: ");
306 print_array(arr1, 8);
307 printf("\n");
308 printf(" 7์ ์์น: %d\n", binary_search(arr1, 8, 7));
309 printf(" 6์ ์์น: %d\n", binary_search(arr1, 8, 6));
310
311 /* 2. Lower/Upper Bound */
312 printf("\n[2] Lower/Upper Bound\n");
313 int arr2[] = {1, 2, 2, 2, 3, 4, 4, 5};
314 printf(" ๋ฐฐ์ด: ");
315 print_array(arr2, 8);
316 printf("\n");
317 printf(" lower_bound(2): %d\n", lower_bound(arr2, 8, 2));
318 printf(" upper_bound(2): %d\n", upper_bound(arr2, 8, 2));
319 printf(" 2์ ๊ฐ์: %d\n", count_occurrences(arr2, 8, 2));
320
321 /* 3. ์ฝ์
์์น */
322 printf("\n[3] ์ฝ์
์์น\n");
323 int arr3[] = {1, 3, 5, 7};
324 printf(" ๋ฐฐ์ด: [1,3,5,7]\n");
325 printf(" 4์ ์ฝ์
์์น: %d\n", search_insert(arr3, 4, 4));
326 printf(" 6์ ์ฝ์
์์น: %d\n", search_insert(arr3, 4, 6));
327
328 /* 4. ํ์ ๋ฐฐ์ด */
329 printf("\n[4] ํ์ ๋ฐฐ์ด ํ์\n");
330 int arr4[] = {4, 5, 6, 7, 0, 1, 2};
331 printf(" ๋ฐฐ์ด: ");
332 print_array(arr4, 7);
333 printf("\n");
334 printf(" 0์ ์์น: %d\n", search_rotated(arr4, 7, 0));
335 printf(" ์ต์๊ฐ: %d\n", find_min_rotated(arr4, 7));
336
337 /* 5. ํ๋ผ๋ฉํธ๋ฆญ ์์น - ๋ฐฐ์ด ๋ถํ */
338 printf("\n[5] ํ๋ผ๋ฉํธ๋ฆญ ์์น - ๋ฐฐ์ด ๋ถํ \n");
339 int arr5[] = {7, 2, 5, 10, 8};
340 printf(" ๋ฐฐ์ด: [7,2,5,10,8], k=2\n");
341 printf(" ์ต๋ ํฉ์ ์ต์๊ฐ: %d\n", split_array_min_max(arr5, 5, 2));
342
343 /* 6. ๋๋ฌด ์๋ฅด๊ธฐ */
344 printf("\n[6] ๋๋ฌด ์๋ฅด๊ธฐ\n");
345 int trees[] = {20, 15, 10, 17};
346 long long target = 7;
347 printf(" ๋๋ฌด ๋์ด: [20,15,10,17], ํ์๋: %lld\n", target);
348 printf(" ์ต๋ ์ ๋จ ๋์ด: %lld\n", cut_trees(trees, 4, target));
349
350 /* 7. ์ค์ ์ด๋ถ ํ์ */
351 printf("\n[7] ์ ๊ณฑ๊ทผ ์ด๋ถ ํ์\n");
352 printf(" sqrt(2): %.6f\n", sqrt_binary_search(2));
353 printf(" sqrt(10): %.6f\n", sqrt_binary_search(10));
354
355 /* 8. ํผํฌ ์ฐพ๊ธฐ */
356 printf("\n[8] ํผํฌ ์ฐพ๊ธฐ\n");
357 int arr8[] = {1, 2, 1, 3, 5, 6, 4};
358 printf(" ๋ฐฐ์ด: [1,2,1,3,5,6,4]\n");
359 int peak_idx = find_peak(arr8, 7);
360 printf(" ํผํฌ ์ธ๋ฑ์ค: %d (๊ฐ: %d)\n", peak_idx, arr8[peak_idx]);
361
362 /* 9. ์๊ณ ๋ฆฌ์ฆ ์์ฝ */
363 printf("\n[9] ์ด๋ถ ํ์ ์์ฉ ์ ๋ฆฌ\n");
364 printf(" | ๋ฌธ์ ์ ํ | ํต์ฌ ์์ด๋์ด |\n");
365 printf(" |------------------|---------------------------|\n");
366 printf(" | lower_bound | arr[mid] < target |\n");
367 printf(" | upper_bound | arr[mid] <= target |\n");
368 printf(" | ํ์ ๋ฐฐ์ด | ์ ๋ ฌ๋ ์ ๋ฐ ์ฐพ๊ธฐ |\n");
369 printf(" | ํ๋ผ๋ฉํธ๋ฆญ | ๊ฒฐ์ ๋ฌธ์ ๋ก ๋ณํ |\n");
370 printf(" | ์ต๋์ ์ต์ | ๊ฐ๋ฅํ ์ต์๊ฐ ์ด๋ถํ์ |\n");
371
372 printf("\n============================================================\n");
373
374 return 0;
375}