http://blog.csdn.net/moien_podiene/article/details/7494929
不知道上面怎么想的 ,下面的思路更简单:
http://blog.csdn.net/lisc741/article/details/8272454
“有M个木板就表明从最小的编号的牛棚到最大的中间有M-1个段可以不覆盖到,找出每两个有牛的牛棚中间隔了多少距离,在这些距离中找前M-1个,这些不用覆盖,那么最小的木板总长度就是整个牛棚的连续长度(最小的编号到最大的)减去这M-1个不用覆盖的长度,就得到答案了”
/*
ID: nenusb1
LANG: C
TASK: barn1
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int cmp(const void * a, const void * b){
return (*(int *)b - *(int *)a);
}
int main(){
freopen("barn1.in","r",stdin);
freopen("barn1.out","w",stdout);
int M,S,C;//max board num, stall num, cow num
scanf("%d %d %d",&M,&S,&C);
int stall[210];
int i;
memset(stall, 0 ,sizeof(stall));
int min = S+1;
int max = 0;
for(i = 1; i <= C; i++){
int temp;
scanf("%d", &temp);
if(temp > max) max = temp;
if(temp < min) min = temp;
stall[temp] = 1;
}
int pre = min;
int j = 0;
int len[210];
memset(len, 0, sizeof(len));
for(i = min; i <= max; i++){
if(stall[i] && i > pre){
len[j++] = i-pre-1;//两头牛中间隔着的棚数
pre = i;
}
}
qsort(len, j, sizeof(int),cmp);
//printf("%d %d %d %d %d\n", len[0], len[1], len[2], max, min);//8 5 3 43 3
int left = 0;
for(i=0; i<M-1; i++){
left += len[i];
}
printf("%d\n", max-min+1-left);
// printf("M=%d S=%d C=%d\n",M,S,C);
return 0;
}