【题目链接】点击此处
牛棚问题:
【问题描述】
在一个暴风雨的夜晚,农民约翰的牛棚的屋顶、门被吹飞了。 好在许多牛正在度假,所以牛棚没有住满。 剩下的牛一个紧挨着另一个被排成一行来过夜。 有些牛棚里有牛,有些没有。 所有的牛棚有相同的宽度。 自门遗失以后,农民约翰必须尽快在牛棚之前竖立起新的木板。他的新木材供应者将会供应他任何他想要的长度,但是供应者只能提供有限数目的木板,农民约翰想将他购买的木板总长度减到最少。
M(1<= M<=50)可能买到的木板最大的数目;
S(1<= S<=200),牛棚的总数;
C(1 <= C <=S) 牛棚里牛的数目,和牛所在的牛棚的编号stall_number(1 <= stall_number <= S),计算拦住所有有牛的牛棚所需木板的最小总长度。
输出所需木板的最小总长度作为的答案。
【输入格式】
第 1 行: M ,S 和 C(用空格分开)
第 2 到 C+1行: 每行包含一个整数,表示牛所占的牛棚的编号。
【输出格式】
单独的一行包含一个整数表示所需木板的最小总长度。
【样例输入】
4 50 18
3
4
6
8
14
15
16
17
21
25
26
27
30
31
40
41
42
43
【样例输出】
25
【分析】
输入的数据未必排好序,因此先对输入的数据排序;
要想木板距离最小,也就是使每两个区间的空隙最大:
如 1,2,3,8,9,10
m = 2;
显然3与8之间的距离最大,就用总距离 - 3与8之间的距离 = 10(max) - 1(min) + 1(得到最大距离) - 8 - 3 - 1得到此时最小木板长度,
也就是相当于1,2,3 与 8,9,10分为两组,共执行了 m-1次分配。
【代码】
1 #include <cstdio> 2 #include <vector> 3 #include <algorithm> 4 5 bool cmp(const int& a, const int& b) { 6 return a > b; 7 } 8 int main() { 9 int m, s, c; 10 scanf("%d %d %d", &m, &s, &c); 11 12 std::vector<int> nodes, distance; 13 for(int i = 0, u; i < c; i++) { 14 scanf("%d", &u); 15 nodes.push_back(u); 16 } 17 sort(nodes.begin(), nodes.end()); 18 for(int i = 0; i != nodes.size() - 1; i++) { 19 int tmp_dis = nodes[i+1] - nodes[i] - 1; 20 if(tmp_dis > 0) { 21 distance.push_back(tmp_dis); 22 } 23 } 24 sort(distance.begin(), distance.end(), cmp); 25 int ans = nodes[nodes.size()-1] - nodes[0] + 1; 26 27 for(int i = 0; i < m - 1 && i < distance.size(); i++) { 28 ans -= distance[i]; 29 } 30 printf("%d", ans); 31 }
代码说明:nodes,有牛的牛棚,并进行一次排序以取得按照顺序的牛棚编号。
distance, 每两个牛棚间的间隙,计算方法为 第二个牛棚编号 - 第一个牛棚编号 - 1
ans,初值为区间总长度,执行m-1次循环以获得最后剩下的长度。