丢瓶盖做题报告
这道题其实之前就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);