1. 程式人生 > 實用技巧 >P1678 煩惱的高考志願 (二分查詢)

P1678 煩惱的高考志願 (二分查詢)

題目連結:P1678

解題思路:

二分查詢找到分差最小的,加起來即可,細節見程式碼註釋

AC程式碼:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cmath>
 4 #include <algorithm>
 5 using namespace std;
 6 int m,n,sum,a[100010],b[100010];
 7 inline int read() // 快讀
 8 {
 9     int x = 0, y = 1; char c = getchar();
10     while
(c < '0' || c > '9') {if(c == '-') y = -1; c = getchar();} 11 while(c >= '0' && c <= '9') x = x*10+c-'0',c = getchar(); 12 return x*y; 13 } 14 int bfind(int x) // 二分,並返回最小分差的絕對值 15 { 16 int l = 0, r = m-1; 17 int mid = (r-l)/2+l; 18 while(l != r) 19 { 20 if
(a[mid] >= x) 21 { 22 r = mid; 23 mid = (r-l)/2+l; 24 } else if(a[mid] < x) { 25 l = mid+1; 26 mid = (r-l)/2+l; 27 } 28 } 29 if(l == 0) return abs(a[l]-x); // 特殊處理l=0情況,不然會re 30 else { 31 int t1,t2; 32 t1 = abs(a[l]-x);
33 t2 = abs(a[l-1]-x); 34 return t1>t2?t2:t1; // 比較兩端,返回最大的 35 } 36 } 37 int main() 38 { 39 sum = 0; 40 m = read(); 41 n = read(); 42 for(int i = 0; i < m; i++) a[i] = read(); 43 for(int i = 0; i < n; i++) b[i] = read(); // 一邊讀入一邊處理TLE了,所以輸入完以後再處理 44 sort(a,a+m); // 只需將分數線排序 45 for(int i = 0; i < n; i++) { 46 sum += bfind(b[i]); 47 } 48 printf("%d",sum); 49 return 0; 50 }