lintcode 281 · 粉刷天花板 【中等 双指针】

题目

https://www.lintcode.com/problem/281/
该题目免费,自己打开看题目。因为有图表,不太好复制过来

思路

	算法:双指针
    算法思路
    我们仔细观察题目里
    s数组生成的式子,我们可以发现
    s数组是递增的,即s i >s i−1

     恒成立。因此,我们要求满足

    si × sj ≤a的(i,j)即可。

    很显然,当sj越来越小的时候,si
    的上界就越来越大。因此,我们可以使用双指针的做法来统计答案。
    右指针指向j,左指针指向i,随着j的减小,i越来越大。

代码

public class Solution {
    /**
     * @param s0: the number s[0]
     * @param n: the number n
     * @param k: the number k
     * @param b: the number b
     * @param m: the number m
     * @param a: area
     * @return: the way can paint the ceiling
     */
    public long painttheCeiling(int s0, int n, int k, int b, int m, long a) {
           /*
        算法:双指针
        算法思路
        我们仔细观察题目里
        s数组生成的式子,我们可以发现
        s数组是递增的,即s i >s i−1

         恒成立。因此,我们要求满足

        si × sj ≤a的(i,j)即可。

        很显然,当sj越来越小的时候,si
        的上界就越来越大。因此,我们可以使用双指针的做法来统计答案。
        右指针指向j,左指针指向i,随着j的减小,i越来越大。
         */
        //公式:s[i] =((k×s[i−1] +b)mod m+1+s[i−1]) for 1≤i
        int[] s = new int[n];  //根据公式求得集合数据
        s[0]= s0;
        for (int i = 1; i <n ; i++) {
            int pre = s[i-1];
            long lk= (long)k;
            long cur = (lk*pre+b)%m + 1+pre;
            s[i] = (int)cur;
        }

        long ans = 0;
        int L=0,R=n-1;
        for(;L<n;L++){
            while (R>=0 && (long)s[L]*s[R] >a){
                R--;
            }

            ans+=(R+1);
        }
        return ans;
    }
}

你可能感兴趣的:(算法)