Topcoder 721 div2-B RememberWordsEasy

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));
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值