首先看看题目:
给定整数区间[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。
对这样的题目,我们首先得进行分析,由于[a, b]内的整数可以做多次加法,每个数字当然也可以重复任意多次;
第一种:如果a = 1;这样的话我们用n个1肯定可以形成x-y的数,所以,这个时候返回y - x + 1;
第二种:如果a == b;这样的话我们只能a来组成x-y之间的数,这样返回y / a - (x - 1) / a;
第三种:这是一般处理的,我们分别将[a, b]组成[1, x - 1],[1, y]这两个区间数的个数,然后将其相减,即可得到[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)
这样的话,由a = 8,b = 10;可以组成8 - 10; 16 - 20; 24 - 30; 32 - 40。。。
它们的个数分别是3 , 5, 7, 9...(等差数列)
所以,如果a = 8,b = 10; x = 3, y = 20;
我们先算它可以先乘几倍,如b = 10可以乘以两次到达20;
count = num / b; //倍数
sum = count * ((b - a + 1) + ((b - a) * count + 1)) / 2; //Sn=n(a1+an)/2
这样将之前的整的就求出来了(通过等差数列求和,因为数会到1000000000,如果模拟的话时间是不够的);
这时候sum = 8;
如果之前的y = 25的话,通过前面的计算后只是到达20而已,后面还有几个数据没有添加进去进行判断是否能够被组成(若y = 25;这样24,25都是可以的;若y = 22这样21,22无法被组成);
if(num >= (count + 1) * a)
sum += num - (count + 1) * a + 1;
加上num >= (count + 1) * a是将之前的基准往后移一位,即由16 - 20到24 - 20;
这样的话就可以将剩余的数有效的计算了;
如果我们将之前的a = 8; b = 10继续扩增的话,我们发现8 - 10; 16 - 20; 24 - 30; 32 - 40;40 - 50; 48 - 60。。。这时我们发现 32 - 40; 40 - 50; 48
- 60这些相邻的都会出现重合的部分,并且往后还会继续重合下去...
if((a % (b - a)) == 0 )
countnum = a / (b - a); //(n + 1)a - nb <= 0
countnum = a / (b - a) + 1;
通过(n + 1)a - nb <= 0;这样我们就可以什么时候会发生重合现象;
如a = 8, b = 10这样countnum = 4;到第五倍的时候就会重合了即40 - 50和前面的32 - 40发生重合;
这样,如果y = 43;
count = 4;
这时:
sum = countnum * ((b - a + 1) + ((b - a) * countnum + 1)) / 2; //Sn=n(a1+an)/2
sum += num - countnum * b;
即将前面的算出来,在40后面的肯定都可以被组合出来,所以会有sum += num - countnum * b;
这样就行了...
主要思想就是这样的,如果大家有什么不清楚的欢迎多多讨论;
由于这个代码英雄会上不便贴出,只上关键的了;
int cover(int a, int b, int num)
{
int count; //次数
int sum = 0; //表示的数
int countnum = 0; //几次之后超过
if((a % (b - a)) == 0 )
countnum = a / (b - a); //(n + 1)a - nb <= 0
countnum = a / (b - a) + 1;
count = num / b;
if(count < countnum) //前面的数未超限
{
sum = count * ((b - a + 1) + ((b - a) * count + 1)) / 2; //Sn=n(a1+an)/2
if(num >= (count + 1) * a)
sum += num - (count + 1) * a + 1;
return sum;
}
else //超限,有重叠
{
sum = countnum * ((b - a + 1) + ((b - a) * countnum + 1)) / 2; //Sn=n(a1+an)/2
sum += num - countnum * b;
return sum;
}
}
没想到这一题竟然有三星难度,捡漏了...
成功进入top100...欢迎贺电,嘿嘿
欢迎大神指点...o(∩_∩)o
分享到:
相关推荐
给定整数区间[a,b]和整数区间[x,y],你可以使用任意多次a,b之间的整数做加法,可以凑出多少个[x,y]区间内的整数? 输入 a,b,x,y,其中1, 1... 答:算1次 问你能覆盖多少个不同的数字 [x,y]全覆盖住得话 就是y - x + 1。
pta题目java的继承覆盖综合题源码,全部内容为自己原创,能够运行但是有些代码可能写的不是很精简,这个摘要也太长了吧,凑不够字数啊
android 全屏幕以按钮覆盖----动态产生按钮并最大化
棋盘覆盖---算法分析与设计 利用了递归实现棋盘的覆盖
棋盘覆盖---JAVA版,带有图形化界面的,挺经典的哦.
给出了覆盖模糊S-粗集上 、下近似算子定义,讨论了算子的基本性质,证明了覆盖S-粗糙集模型下所有模糊集的下近似构成一个模糊拓扑,并得到模糊单向S-粗集X相对于覆盖单向S-粗集和覆盖约简单向S-粗集的上下近似分别...
同覆盖工具-V0.2.6-测试版 (2)--无试用期 - 副本同覆盖工具-V0.2.6-测试版 (2)--无试用期 - 副本同覆盖工具-V0.2.6-测试版 (2)--无试用期 - 副本同覆盖工具-V0.2.6-测试版 (2)--无试用期 - 副本同覆盖工具-V0.2.6-...
数字技术在广播电视无线覆盖的运用-广播电视-通信传播.pdf
1.用patch文件夹下的文件覆盖myeclipse2017安装目录下的 plugins 2.运行keygen目录的crack.bat a.输入Usercode: 任意字母或者数字 b.选择Blue c.点击SystemId(点两次才会生成) d.点击Active e.点击菜单栏->...
台湾版:覆盖网络NS-2模拟 Overlay Network for NS-2 Simulation。 覆盖网络NS-2模拟开创性工作,相当经典!
深度覆盖项目--分销团队操作手册.doc
右击管理员运行Patch.exe注册机,任意位置运行,无须拷到程序目录,本程序会自动停止Serv-U服务,无须手动停止,勾选 Key和Backup两个选项,然后点Patch完成注册; 如果出现“File Serv-U.dll obscure”提示而无法...
覆盖规划报告 -.docx
每个基站的有效覆盖范围为10Km,欲让基站信号覆盖所有小区,求解最小的基站数目以及其位置。 1. 设立两个鸟巢(1*m维数组),称为x_nest, y_nest。对应位置的组合即为一个基站位置。m表示当前选用m个基站。 2. 适应...
2.输入Usercode: 任意字母或者数字 3.选择Blue 4.点击SystemId(点两次才会生成) 5.点击Active 6.点击菜单栏->Tools->2.saveProperties 7.用patch文件夹中的内容 覆盖添加到myeclipse安装目录下的 plugins文件夹中 ...
2011-2022年省市县数字普惠金融指数、数字金融覆盖广度、数字金融使用深度等 指标数据 1、时间:2011-2022年 其中县级的时间为2014-2022年 2、范围:全国31省,337个地级市以及2800个县 3、指标:覆盖广度、使用深 ...
全域覆盖 场景智联-6G场景、能力与技术引擎白皮书
Java 实例 - 方法覆盖源代码-详细教程.zip
白盒测试-逻辑覆盖测试方法 - (张三).doc
1.用patch文件夹下的文件覆盖myeclipse2017安装目录下的 plugins 2.运行keygen目录的crack.bat a.输入Usercode: 任意字母或者数字 b.选择Blue c.点击SystemId(点两次才会生成) d.点击Active e.点击菜单栏->...