usaco 1.3 Barn Repair(贪心)


思路:用上M块木板时有 M-1 个间隙。目标是让总间隙最大。将相邻两个有牛的牛棚之间间隔的牛棚数排序,选取最大的M-1个作为间隙,其余地方用木板盖住。


做法:

1.若,板(M) 的数目大于或等于 牛棚中有牛的数目(C),则 目测 给每个牛牛发一个板就为最小的需求~

2.否则,先对 牛牛们的门牌号排序,然后 用一个数组 blank[ ] 记录两门牌号之间的距离,然后 用数组 ans[  ]标记下头门牌和尾门牌,用自定义的searchmax()函数找出最大门牌的空白,用数组ans[ ]记录下两相邻门牌,最后对门牌排序,减减加加,即为猜想的答案。


Ps.....刚开始的时候容易漏掉第一种情况,以后做题要谨慎,如果没有后台数据了不要又检查不出来~~~~~~~~~~~~~~~


代码:

/*
ID: who jay
LANG: C++
TASK: barn1
*/
#include<stdio.h>
#include<stdlib.h>

int cmp(const void *a,const void *b)
{
    return *(int*)a-*(int*)b;
}

int searchmax(int A[],int n)
{
    int i,vi,max=0;
    for(i=0; i<n; i++)
    {
        if(A[i]>max)
        {
            max=A[i];
            vi=i;
        }
    }
    return vi;
}

int main()
{
    FILE *fin  = fopen ("barn1.in", "r");
    FILE *fout = fopen ("barn1.out", "w");
    int M,S,C,vi,i,ans[100],s[200],blank[200],sum;
    while(fscanf(fin,"%d%d%d",&M,&S,&C)!=EOF)
    {
        for(i=0; i<C; i++)
            fscanf(fin,"%d",&s[i]);
        if(M>=C)
            fprintf(fout,"%d\n",C);
        else
        {
            sum=0;
            qsort(s,C,sizeof(s[0]),cmp);

            blank[0]=0;
            for(i=1; i<C; i++)
            {
                blank[i]=s[i]-s[i-1];
            }
            ans[2*M-2]=s[0];
            ans[2*M-1]=s[C-1];

            for(i=0; i<M-1; i++)
            {
                vi=searchmax(blank,C);
                ans[i]=s[vi];
                ans[M+i-1]=s[vi-1];
                blank[vi]=0;
            }
            qsort(ans,2*M,sizeof(ans[0]),cmp);

            for(i=1; i<2*M; i+=2)
            {
                sum+=(ans[i]-ans[i-1]+1);
            }
            fprintf(fout,"%d\n",sum);
        }
    }
    return 0;
}


你可能感兴趣的:(usaco 1.3 Barn Repair(贪心))