丢瓶盖做题报告

这道题其实之前就A了,现在再做一遍反而调了一下午。

二分答案的模板和思路都没问题。调的主要是check函数。

话不多说,先看看我第一次和第二次写的check

bool check(int x) {//1
    int sum=0;
    for(int i=2; i<=A; i++) {
        sum=0;
        for(int j=1; j<i; j++) {
            if(a[i]-a[j]>=x) {
                sum++;
            }
            if(sum == B) {
                return true;
            } 
        }
    }
    return sum>=B;
}
bool check(int x) {//2
    int sum=0;
    for(int j=1; j<A; j++) {
        if(abs(a[A]-a[j])>=x) {
            sum++;
        }
        if(sum == B) {
            return true;
        } 
    }
    return sum>=B;
}

评价:狗屁不通,题意都理解错了。必须是相邻两个瓶盖之间求距离。而我上面两个做法是先选定一个点,再枚举

除了他以外的所有点。显然是不对的。而且sum的初始值显然是应该为一的。

然后我调了半天,终于挑了一个应该可以保证正确性的check

void check(int num,int x,int p,int sum) {
    //printf("num=%d sum=%d x=%d last=%d\n",num,sum,x,p);
    if(pd == true) {
        return ;
    }
    if(num == B) {
        pd=(sum>=(B-1));
    }
    if(sum >= (B-1)) {
        pd=true;
        return ;
    }
    for(int i=p+1; i<=A; i++) {
        if(a[i]-a[p]>=x && p) {
            check(num+1,x,i,sum+1);
        } else {
            check(num+1,x,i,sum);   
        }
    }
}

没错我用了搜索。。。然鹅只得了$30pts$,其他点全都超时了。

然后我从题解区get到了一个很简单的check

bool check(int x) {
    //printf("num=%d sum=%d x=%d last=%d\n",num,sum,x,p);
    int num=1,sum=1;
    for(int i=2; i<=A; i++) {
        if(a[i]-a[num]>=x) {
            num=i;
            sum++;
        }
        if(sum>=B){
            return true;
        }
    }
    return sum>=B;
}

这个看代码就可以理解为什么了。

然后再二分上也栽了点跟头。

总之给出二分答案的模板

l=0,r=n;
while(l+1 < r) {
    mid=(l+r)>>1;
    if(check(mid)) {
        l=mid;
    } else {
        r=mid;
    }
}
printf("%d",l);
posted @ 2019-02-02 18:30  加固文明幻景  阅读(3)  评论(0编辑  收藏  举报  来源