数字覆盖问题的一种解法

      数字覆盖问题,没什么解题思想,如果说有的话,就是数学观察,代码如下

package com.wly.algorithmproblem;

/**
 * 数字覆盖问题
 * 
	 
	题目详情
	给定整数区间[a,b]和整数区间[x,y],你可以使用任意多次a,b之间的整数做加法,可以凑出多少个[x,y]区间内的整数?
	输入 a,b,x,y,其中1<= a < b <= 1000000000,  1 <= x < y <= 1000000000。
	输出: 用[a,b]内的整数做任意多次加法,可以得到多少个[x,y]内的整数。
	
	例如a = 8, b = 10, x = 3 , y = 20
	我们可以得到 [3..20]之间的整数 8, 9, 10, 16 ( 8 + 8), 17(8 + 9), 18(9 + 9), 19(9 + 10), 20(10 + 10),因此输出8。
	
	问:2+3=5 1+4=5 这算1个还是2个?
	答:算1次 问你能覆盖多少个不同的数字 [x,y]全覆盖住得话 就是y - x + 1。
 * @author wly
 *
 */
public class howmany {

	public static void main(String[] args) {
		long time1;
//		int max = 10000;
		int max = 1000000000;
		time1 = System.currentTimeMillis();
		System.out.println("m1:" + howmany(3,4,10,max)); //999999440,5242
		System.out.println(System.currentTimeMillis() - time1);
		
		time1 = System.currentTimeMillis();
//		System.out.println("m2:" + howmany2(400000000,400000050,1,1000000000)); //33993551
		System.out.println("m2:" + howmany2(3,4,10,max)); //33993551
		System.out.println(System.currentTimeMillis() - time1);
	}
	
	public static int howmany(int a,int b,int x,int y) {
		int num = 0;
		long times = 0;
		
		if(x < a) {
			x = a;	
		}
		
		for(int i=x;i<=y;i++) {
			times = i /a;
			if(times*b >= i) {
				num ++;
//				System.out.print(i + " ");
			} else {
				continue ;
			}
		}
		return num;
	}
	
	/**
	 * 结题思想:
	 * 本解法基本没有使用算法思想,主要是从数学推理解得的,根据题目要求若x可用[m,n]表示,则x属于[c*m,c*(m+n)],其中c是>=1的正整数
	 * 或者说[c*m,c*(m+n)]中的元素总是可以用[m,n]中的元素来表示
	 * 公式推理过程:设一个[c*m,c*(m+n)]中的数c*m + an + b,则c*m + an + b = a(m+n) + (c-a)m * b,其中1<=b<=n
	 * @param a
	 * @param b
	 * @param x
	 * @param y
	 * @return
	 */
	public static int howmany2(int a,int b,int x,int y) {
		int num = 0;
		long times = 0;
		
		if(a >= b || x >= y) {
			return 0;
		}
		if(x < a) {
			x = a;	
		}
	
		//优化解法
		int i = x; //-------就因为这里出错了,哎,,,
		while(i <= y) { //使用while来实现i的改变
			times = i /a; 
			if(times*b > i) {
				int delta;
				if(times*b >= y) {
					delta = (int) (y - i+1);
				} else {
					delta = (int) (times*b - i+1);
				}
				
				num = (int)(num + delta);
				i = delta + i;
//				System.out.print(i + " ");
			} else if(times*b == i) {
				i ++;
				num ++;
			} else { //无解情况
				i ++;
			}
		}
		
		return num;
	}
}
       运行结果:
m1:999999991
3430
m2:999999991
0

       O啦~~~

       转载请保留出处:http://blog.csdn.net/u011638883/article/details/17369445

       谢谢!!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值