纠结于一个循环

做成电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,从而多了一次进入循环的机会,刚好把第一个没加的柱子补上了。

 

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

posted @ 2013-03-29 18:24  学习中的小毛  阅读(190)  评论(1编辑  收藏  举报