覆盖数字

/**
 * 覆盖数字
 * 
 * 给定整数区间[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 zoyation
 * 
 */
public class OverWriteNumber {
	public static int howmany(int a, int b, int x, int y) {
		/*
		 * Scanner sc = new Scanner(System.in); 获取输入abcd输入,1<= a < b <=
		 * 1000000000,1 <= x < y <= 1000000000 while (a <= 0 || a >= 999999999
		 * || b <= a || b >= 1000000000 || x <= 0 || x >= 999999999 || y <= x ||
		 * y >= 1000000000) { if (a <= 0 || a >= 999999999) {
		 * System.out.print("请输入a的值([1,999999999]):"); a = sc.nextInt(); if (a
		 * <= 0 || a >= 999999999) {
		 * System.out.println("a的值不在区间[1,999999999]内,请重新输入!"); } } else if (b <=
		 * a || b >= 1000000000) { System.out.print("请输入b的值([a+1=" + (a + 1) +
		 * ",999999999]):"); b = sc.nextInt();
		 * 
		 * if (b <= a || b >= 1000000000) { System.out.println("b的值不在区间[a+1=" +
		 * (a + 1)+ ",999999999]内,请重新输入!"); } } else if (x <= 0 || x >=
		 * 999999999) { System.out.print("请输入x的值([1,999999999]):"); x =
		 * sc.nextInt();
		 * 
		 * if (x <= 0 || x >= 999999999) {
		 * System.out.println("x的值不在区间[1,999999999]内,请重新输入!"); } } else if (y <=
		 * x || y >= 1000000000) { System.out.print("请输入y的值([x+1=" + (x + 1) +
		 * ",999999999]):"); y = sc.nextInt();
		 * 
		 * if (y <= x || y >= 1000000000) { System.out.println("y的值不在区间[x+1=" +
		 * (x + 1)+ ",999999999]内,请重新输入!"); } } } System.out.println("a=" + a +
		 * ",b=" + b + ",x=" + x + ",y=" + y);
		 */
		/* count 记录能覆盖多少个不同的数字 */
		int count = 0;
		if (a > y) {
			count = 0;
		} else if (a == y) {
			count = 1;
		} else {
			int i = a >= x ? a : x;// 记录遍历起始[x,y]值

			if (b >= y) {
				/* b比y大,直接计算 */
				count = y - i + 1;
			} else {
				int k = 0;/* 记录开始在区间[x,y]通过循环计算统计的最小数 */
				if (b < x) { /* a<b<x */
					count = 0;
					k = x;
				} else {
					count = b - i + 1;
					k = b + 1;
				}
				/* 下面遍历统计覆盖数字 */
				int t1 = a;
				int t2 = b;
				do {
					int m1 = k % t1;
					if (m1 >= a || m1 == 0) {
						/*当前统计数和t1求余,如果为0或者不比a小,在区间[a,t1)内,k=t1*n+m1(n=k/t1)*/
						count++;
						// System.out.println("m1="+m1+",t1="+t1+",k="+k);
						t1 = a;
						t2 = b;
						k++;
					} else {
						int m2 = k % t2;

						if (m2 >= a || m2 == 0) {
							/*当前统计数和t1求余,如果为0或者不比a小,在区间[a,t2)内,k=t2*n+m2 (n=k/t2)*/
							count++;
							// System.out.println("m2="+m2+",t2="+t2+",k="+k);
							t1 = a;
							t2 = b;
							k++;
						} else {
							t1++;
							t2--;
							/* t1大于t2时,[a,b]区间值都取过了,重新开始下一个数的验证 */
							if (t1 > t2) {
								t1 = a;
								t2 = b;
								k++;
							}
						}
					}

				} while (k <= y);
			}
		}

		return count;
	}

	public static void main(String args[]) {
		System.out.println(howmany(51, 52, 50, 999999999));// 57315234
	}
}


 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值