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 }

 

posted @ 2020-09-12 22:30  不敢说的梦  阅读(322)  评论(0)    收藏  举报