题意:牛奶长共有S个牛栏,编号从1~S。在暴风雨中所有的牛栏的门都损坏了。牛栏不是满员,而是只有C个有牛。现在有M段木板,每段木板可以任意长,可以用来封死任意个相邻的牛栏。所需要求的是,在保证有牛的牛栏都被封死的情况,用这M段木板最少封死多少个牛栏?
解题思路:
- 如果M>=C,那么很简单,用C段木板封死每一个有牛的牛栏即可,这种情况下需要C段木板
- 如果M<C。那么先假设用1段超长的木板封死从第一个有牛的牛栏到最后一个有牛的牛栏。因为我们需要求最少封死多少个牛栏,所以对于一些没有牛的牛栏,我们需要进行木板的拆除。每一次拆除一段木板都会使所使用的木板数+1,而每次拆除都会减少封死牛栏的数量。既然需要求最少封死多少个牛栏,那么我们应该尽量多地拆除木板,最多拆除M-1段。对于这M-1段被拆除的木板,每次选取为间隔最远的那两个有牛的牛栏之间的木板。
代码:
/*
ID: zc.rene1
LANG: C
PROG: barn1
*/
#include<stdio.h>
#include<stdlib.h>
int find_max(int arr[], int c){
int max=-1;
int max_index=-1;
int i;
for(i=0; i<c; i++){
if(arr[i]>=max){
max=arr[i];
max_index=i;
}
}
return max_index;
}
void sort_arr(int arr[], int c){
int i, j, temp;
for(i=c-1; i>0 ;i--){
for(j=0; j<i; j++){
if(arr[j]>arr[j+1]){
temp=arr[j+1];
arr[j+1]=arr[j];
arr[j]=temp;
}
}
}
}
int main(void){
int m, s, c, i, total, index;
FILE *fin=fopen("barn1.in", "r");
FILE *fout=fopen("barn1.out", "w");
fscanf(fin, "%d %d %d", &m, &s, &c);
int * arr=(int *)malloc(c*sizeof(int));
int * arr_gap=(int *)malloc(c*sizeof(int));
for(i=0; i<c; i++){
fscanf(fin, "%d", &arr[i]);
}
sort_arr(arr, c);
arr_gap[0]=0;
for(i=1; i<c; i++){
arr_gap[i]=arr[i]-arr[i-1];
}
if(m>=c){
total=c;
}
else{
total=arr[c-1]-arr[0]+1;
for(i=1; i<m; i++){
index=find_max(arr_gap, c);
total-=(arr_gap[index]-1);
arr_gap[index]=0;
}
}
fprintf(fout, "%d\n", total);
return 0;
}