P1678 烦恼的高考志愿

P1678题库链接:https://www.luogu.org/problem/P1678

难度:普及-

算法标签:模拟,贪心,排序,二分查找

1.朴素模拟 O(m*n) 得分30

先将m个学校的录取分数线排序,再用每名考生的成绩依次寻找第i个大学(若某个大学的录取分数线大于等于考生的成绩,即为第i个大学),该考生的成绩在第i-1个与第i个大学的录取分数线之间,用第i-1个和第i个大学的录取分数线分别减去该考生的成绩,取绝对值,因为要求出最小值,则用sum加上两者取绝对值后的较小值,最后sum即为答案

 1 #include <cstdio>
 2 #include <algorithm>
 3 using namespace std;
 4 int m, n, a[100010], b[100010];
 5 int main()
 6 {
 7     scanf("%d%d", &m, &n);
 8     int sum = 0;
 9     for(int i = 0; i < m; ++i)
10         scanf("%d", &a[i]);
11     for(int i = 0; i < n; ++i)
12         scanf("%d", &b[i]);
13     sort(a, a + m);
14     for(int i = 0; i < n; ++i)
15     {
16         for(int j = 0; j < m; ++j)
17         {
18             if(b[i] <= a[j])
19             {
20                 if(j == 0) sum += a[0] - b[i];
21                 else sum += min(abs(a[j] - b[i]), abs(a[j - 1] - b[i]));
22                 break;
23             }
24         }
25     }
26     printf("%d\n", sum);
27     return 0;
28 } 

2.二分查找优化 O(log(m)*n) 得分100

利用二分查找来找到每名考生的第i个大学,其查找过程只需要log(m)次,可以解决时间复杂度较大的问题,其余与朴素算法同理

 1 #include <cstdio>
 2 #include <algorithm>
 3 using namespace std;
 4 int m, n, a[100010], b[100010];
 5 int main()
 6 {
 7     scanf("%d%d", &m, &n);
 8     int sum = 0;
 9     for(int i = 0; i < m; ++i)
10         scanf("%d", &a[i]);
11     for(int i = 0; i < n; ++i)
12         scanf("%d", &b[i]);
13     sort(a, a + m);
14     for(int i = 0; i < n; ++i)
15     {
16         int l = 0, r = m - 1;
17         while(l < r)
18         {
19             int mid = (l + r) / 2;
20             if(b[i] >= a[mid]) l = mid + 1;
21             else if(b[i] < a[mid]) r = mid;
22         }
23         if(b[i] <= a[0]) sum += a[0] - b[i];
24         else sum += min(abs(a[l - 1] - b[i]), abs(a[l] - b[i]));
25     }
26     printf("%d\n", sum);
27     return 0;
28 } 

猜你喜欢

转载自www.cnblogs.com/ZhangRunqi/p/11297431.html
今日推荐