• 数字覆盖问题的一种解法


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

    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

           谢谢!!

  • 相关阅读:
    拳击游戏(虚函数应用)
    虚函数的使用
    继承中的二义性归属问题
    继承的作用以及在子类中初始化所有数据的方法
    Exploring ES2016 Decorators
    Storage information for PWA application
    浏览器中常见网络协议介绍
    vuex所有核心概念完整解析State Getters Mutations Actions
    搭建一个webpack微服务器
    nodeJS接入微信公众平台开发
  • 原文地址:https://www.cnblogs.com/fuhaots2009/p/3478645.html
Copyright © 2020-2023  润新知