题目
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<n
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;
}
}