USCAO section1.3 Barn Repair

 
 

Barn Repair

It was a dark and stormy night that ripped the roof and gates off the stalls that hold Farmer John's cows. Happily, many of the cows were on vacation, so the barn was not completely full.

The cows spend the night in stalls that are arranged adjacent to each other in a long line. Some stalls have cows in them; some do not. All stalls are the same width.

Farmer John must quickly erect new boards in front of the stalls, since the doors were lost. His new lumber supplier will supply him boards of any length he wishes, but the supplier can only deliver a small number of total boards. Farmer John wishes to minimize the total length of the boards he must purchase.

Given M (1 <= M <= 50), the maximum number of boards that can be purchased; S (1 <= S <= 200), the total number of stalls; C (1 <= C <= S) the number of cows in the stalls, and the C occupied stall numbers (1 <= stall_number <= S), calculate the minimum number of stalls that must be blocked in order to block all the stalls that have cows in them.

Print your answer as the total number of stalls blocked.

PROGRAM NAME: barn1

INPUT FORMAT

Line 1:M, S, and C (space separated)
Lines 2-C+1:Each line contains one integer, the number of an occupied stall.

SAMPLE INPUT (file barn1.in)

4 50 18
3
4
6
8
14
15
16
17
21
25
26
27
30
31
40
41
42
43

OUTPUT FORMAT

A single line with one integer that represents the total number of stalls blocked.

SAMPLE OUTPUT (file barn1.out)

25
[One minimum arrangement is one board covering stalls 3-8, one covering 14-21, one covering 25-31, and one covering 40-43.]

解题思路:题意是将一个区间分为N个小区间使得小区间间隔的和最小。
       1:将区间排序为有序区间
       2:算出每个区间间隔并排序
       3:将区间尾首相减在减去允许分的M个最大间隔
      当允许划分的间隔大于区间个数直接输出区间个数即可
 
 
 
/*
ID:nealgav1
PROG:barn1
LANG:C++
*/
#include<cstdio>
#include<algorithm>
#define N 1234
using namespace std;
int line[N];
bool cmp(int a,int b)
{
  return a<b;
}
int main()
{
  freopen("barn1.in","r",stdin);
  freopen("barn1.out","w",stdout);
  int n,m,cas;
  while(scanf("%d%d%d",&n,&m,&cas)!=EOF)
  {
    for(int i=0;i<cas;i++)
    scanf("%d",&line[i]);
    if(n>cas)
    printf("%d\n",cas);
    else
    {
      sort(line,line+cas,cmp);
    int ans=line[cas-1]-line[0];
    for(int i=0;i<cas-1;i++)
    line[i]=line[i+1]-line[i];
    sort(line,line+cas-1,cmp);
    int j=cas-2;
    for(int i=0;i<n-1;i++)//减少一个
    ans-=line[j--];
    printf("%d\n",ans+n);
   }
  }
}

 
 
 
 
 
 
 
Barn Repair Russ Cox

If we can purchase M boards, then we can leave unblocked M-1 runs of stalls without cows in them, in addition to any stalls on the leftmost side that don't have cows and any stalls on the rightmost side that don't have cows.

We input the list of cows in stalls, storing into an array whether or not there is a cow in a particular stall. Then we walk the array counting sizes of runs of cowless stalls. We sort the list of sizes and pick the M-1 largest ones as the stalls that will remain uncovered.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#define MAXSTALL 200
int hascow[MAXSTALL];

int
intcmp(const void *va, const void *vb)
{
	return *(int*)vb - *(int*)va;
}

void
main(void)
{
    FILE *fin, *fout;
    int n, m, nstall, ncow, i, j, c, lo, hi, nrun;
    int run[MAXSTALL];

    fin = fopen("barn1.in", "r");
    fout = fopen("barn1.out", "w");
    
    assert(fin != NULL && fout != NULL);

    fscanf(fin, "%d %d %d", &m, &nstall, &ncow);
    for(i=0; i<ncow; i++) {
	fscanf(fin, "%d", &c);
	hascow[c-1] = 1;
    }

    n = 0;	/* answer: no. of uncovered stalls */

    /* count empty stalls on left */
    for(i=0; i<nstall && !hascow[i]; i++)
	n++;
    lo = i;

    /* count empty stalls on right */
    for(i=nstall-1; i>=0 && !hascow[i]; i--)
	n++;
    hi = i+1;

    /* count runs of empty stalls */
    nrun = 0;
    i = lo;
    while(i < hi) {
	while(hascow[i] && i<hi)
	    i++;

	for(j=i; j<hi && !hascow[j]; j++)
	    ;

	run[nrun++] = j-i;
	i = j;
    }

    /* sort list of runs */
    qsort(run, nrun, sizeof(run[0]), intcmp);

    /* uncover best m-1 runs */
    for(i=0; i<nrun && i<m-1; i++)
	n += run[i];

    fprintf(fout, "%d\n", nstall-n);
    exit(0);
}
Alexandru Tudorica's solution might be simpler:
var f:text;
    a,b:array[1..1000] of longint;
    i,m,s,c,k:longint;

procedure qsort(l,r:longint);
    var i,j,x,y:longint;
begin
     i:=l; j:=r; x:=a[(l+r) div 2];
     repeat
           while a[i]<x do i:=i+1;
           while x<a[j] do j:=j-1;
           if i<=j then begin
                y:=a[i]; a[i]:=a[j]; a[j]:=y;
                i:=i+1;
                j:=j-1;
           end;
     until i>j;
     if l<j then qsort(l,j);
     if i<r then qsort(i,r);
end;

procedure qsortb(l,r:longint);
    var i,j,x,y:longint;
begin
     i:=l; j:=r; x:=b[(l+r) div 2];
     repeat
           while b[i]<x do i:=i+1;
           while x<b[j] do j:=j-1;
           if i<=j then
           begin
                y:=b[i]; b[i]:=b[j]; b[j]:=y;
                i:=i+1;
                j:=j-1;
           end;
     until i>j;
     if l<j then qsortb(l,j);
     if i<r then qsortb(i,r);
end;


begin
     assign(f,'barn1.in');
     reset(f);
     readln(f,m,k,c);
     for i:=1 to c do readln(f,a[i]);
     qsort(1,c);
     for i:=1 to c-1 do b[i]:=a[i+1]-a[i]-1;
     qsortb(1,c-1);
     for i:=c-1 downto (c-m+1) do s:=s+b[i];
     close(f);
     assign(f,'barn1.out');
     rewrite(f);
     writeln(f,a[c]-a[1]-s+1);
     close(f);
end.

 
 
 
 
 
 
 
 
 
USER: Neal Gavin Gavin [nealgav1]
TASK: barn1
LANG: C++

Compiling...
Compile: OK

Executing...
   Test 1: TEST OK [0.000 secs, 3352 KB]
   Test 2: TEST OK [0.000 secs, 3352 KB]
   Test 3: TEST OK [0.000 secs, 3352 KB]
   Test 4: TEST OK [0.000 secs, 3352 KB]
   Test 5: TEST OK [0.000 secs, 3352 KB]
   Test 6: TEST OK [0.000 secs, 3352 KB]
   Test 7: TEST OK [0.000 secs, 3352 KB]
   Test 8: TEST OK [0.000 secs, 3352 KB]
   Test 9: TEST OK [0.000 secs, 3352 KB]
   Test 10: TEST OK [0.000 secs, 3352 KB]

All tests OK.

Your program ('barn1') produced all correct answers! This is your submission #2 for this problem. Congratulations!

Here are the test data inputs:

------- test 1 ----
4 50 17
3
4
6
8
14
15
16
17
25
26
27
30
31
40
41
42
43
------- test 2 ----
2 10 4
2
4
6
8
------- test 3 ----
3 27 16
2
3
5
6
8
9
10
13
14
15
16
19
20
21
22
27
------- test 4 ----
1 200 8
101
105
102
106
103
107
104
99
------- test 5 ----
50 200 10
18
69
195
38
73
28
6
172
53
99
------- test 6 ----
50 30 6
30
25
20
15
10
5
------- test 7 ----
20 200 80
65
178
64
70
18
32
88
90
98
20
152
31
118
117
127
81
175
73
136
161
165
63
130
133
190
10
4
138
200
43
189
37
86
182
145
110
67
126
114
153
99
25
155
119
176
55
48
197
62
147
125
60
12
23
112
96
27
122
35
50
36
49
149
108
100
188
77
191
6
121
166
132
82
95
150
89
22
40
128
56
------- test 8 ----
4 200 100
72
180
46
198
196
131
165
112
52
133
187
93
57
35
128
65
127
130
12
49
88
155
122
193
101
164
98
143
54
149
38
84
45
139
79
16
102
20
14
150
188
33
176
135
29
80
19
74
11
114
95
185
137
59
32
189
66
67
191
91
77
134
18
10
7
200
8
13
55
24
142
184
17
6
109
105
43
181
85
94
151
160
115
25
116
111
37
104
144
97
90
141
120
119
152
182
123
172
40
23
------- test 9 ----
20 195 100
1
2
3
4
5
11
12
13
14
15
21
22
23
24
25
31
32
33
34
35
41
42
43
44
45
51
52
53
54
55
61
62
63
64
65
71
72
73
74
75
81
82
83
84
85
91
92
93
94
95
101
102
103
104
105
111
112
113
114
115
121
122
123
124
125
131
132
133
134
135
141
142
143
144
145
151
152
153
154
155
161
162
163
164
165
171
172
173
174
175
181
182
183
184
185
191
192
193
194
195
------- test 10 ----
1 200 2
1
200

转载于:https://www.cnblogs.com/nealgavin/archive/2012/07/10/3206050.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值