纠结于一个循环

做成电oj的1006,参考了网上的代码http://blog.163.com/gcb_1991/blog/static/1715021672011313101440112/

for(i=0; i<n; i++)
{
    for(j=i+1; j<n&&(a[i].h-a[j].h)/(a[j].x-a[i].x)>=c; j++);
    i=j-1;
    m++;
}

他的思路是这样的,从第一个柱子开始,直到这个柱子的影子不能盖住某个柱子为止,那么不能被完全覆盖的柱子数就加一。

然后再从这个柱子开始找下一个不能被完全覆盖的柱子。

现在的问题是,第一个柱子肯定是不能被覆盖的,但是这段代码第一次计数加一的位置并不是第一个柱子处,而是从不能被第一个柱子的影子覆盖的那个柱子开始的。

莫非这段程序写错了么?

原来蹊跷在于循环的终止处,如果最后一个柱子可以被覆盖,那么j就会由于不满足j<n这个条件而跳到n,i=n-1,计数m增加后,无法再次进入循环,所以这里相当于把第一个没加的柱子补上了。

如果最后一个柱子不能被覆盖,那么j就会由于不满足(a[i].h-a[j].h)/(a[j].x-a[i].x)>=c这个覆盖的判定条件而跳到n-1(也就是最后一个柱子本身),此时的计数m++加的是最后一个不能被覆盖的柱子,比较微妙的是,此时i=j-1后其值等于n-2,从而多了一次进入循环的机会,刚好把第一个没加的柱子补上了。

 

反正,我不准备再纠结这个东西了(挥泪)......

转载于:https://www.cnblogs.com/math-mao/archive/2013/03/29/2989402.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值