Topcoder RememberWordsEasy
题目描述
div2-B
https://community.topcoder.com/stat?c=problem_statement&pm=14708
div1-A
https://community.topcoder.com/stat?c=problem_statement&pm=14707
唯一的区别在于d,w的范围。
问题解法计算d1区间的最后一个数字范围,计算d2区间的第一个数字可取范围
在w区间在[1,1000000]的时候,可以使用遍历的方式找到最大值。
在w区间在[1,1000000000]的时候,遍历的方式时间不能满足,因为计算满足起始数字的公式满足单调,所以可以通过二分的方式确定起始数字的范围。
代码示例
import java.math.BigInteger;
/**
* Created by liang on 2017/10/2.
*/
public class RememberWordsEasy {
public boolean f(int i, int d, int w){
int l = i - d + 1;
int r = i + d - 1;
BigInteger s,p;
if(l<0) {
s = BigInteger.valueOf((i)).multiply(BigInteger.valueOf(i+1)).divide(BigInteger.valueOf(2));
}else{
s = BigInteger.valueOf(l+i).multiply(BigInteger.valueOf(d)).divide(BigInteger.valueOf(2));
}
p = BigInteger.valueOf(i+r).multiply(BigInteger.valueOf(d)).divide(BigInteger.valueOf(2));
if(s.compareTo(BigInteger.valueOf(w))<=0 && p.compareTo(BigInteger.valueOf(w))>=0)
return true;
else
return false;
}
class result {
int min;
int max;
}
public result ff(int d, int w){
result ans = new result();
int l = 0;
int r = w/d;
int mid = 0;
while(r-l>=0){
mid = (l+r)/2;
if(f(mid, d, w)){
ans.min = mid;
r = mid-1;
}else{
l = mid+1;
}
}
l = w/d;
r = w;
while(r-l >= 0 ){
mid = (l+r)/2;
if(f(mid, d, w)){
l = mid+1;
ans.max = mid;
}else{
r = mid-1;
}
}
System.out.println(ans.min);
System.out.println(ans.max);
return ans;
}
public String isPossible(int d1, int d2, int w1, int w2){
result ans1 = ff(d1, w1);
result ans2 = ff(d2, w2);
if (ans1.min-1 > ans2.max || ans1.max+1 < ans2.min){
return "Impossible";
}else{
return "Possible";
}
}
public static void main(String[] args) {
RememberWordsEasy r = new RememberWordsEasy();
int d1 = 1;
int d2 = 1;
int w1 = 2;
int w2 = 3;
System.out.println(r.isPossible(d1, d2, w1, w2));
}
}