沿着Waa放大是一个由SKIT数学系组织的简单游戏。游戏的目标是按正在递增的顺序说正整数,有一个转折点:你没有说可以被3和5整除的数字。相反,每当一个数字可以被3整除时,你会说“缩放”并且数字可以被整除5你说“waa”。 (因此,如果一个数字可以被15整除,你会说“zoomwaa”。)
以下是游戏的开始方式:
1, 2, zoom, 4, waa, zoom, 7, 8, zoom, waa, 11, zoom, 13, 14, zoomwaa,
16, 17, zoom, 19, waa, zoom, 22, 23, zoom, waa, 26, zoom, 28, 29,
zoomwaa, 31, 32, zoom, 34, waa, zoom, ...
放大Waa也成为SKIT CS学生的传统编程问题。但是,在这个问题上,我们有一个更棘手的任务。
给予长A和B.考虑游戏中与A到B的整数对应的部分。在这部分游戏中,你会说“缩放”X次,“waa”Y次,“zoomwaa”Z次。你必须确定X,Y和Z。
输入:
第一行输入包含一个整数T,表示测试用例的数量。每个测试用例都有一行输入,包含两个空格分隔的整数,A和B.
输出
在每个测试用例的空格分隔上打印X,Y和Z的值。
约束:
1< = A< = 10 ^ 18
A< = B< = 10 ^ 18
1< = T< = 4左
示例输入(明文链接)
4
1 4
2 6
150 165
474747 747474
示例输出(明文链接)
1 0 0
2 1 0
4 2 2
72728 36363 18182
我的代码如下所示
#include<iostream>
using namespace std;
int main()
{
long long num[2];
int t,i,j,ii,jj,kk;
//--t is number of test inputs--//
cin>>t;
for(i=0;i<t;i++)
{
<!--ii increments if number is divisible by 3 i.e., number is Zoom--
--jj increments if number is divisible by 5 i.e., number is Waa--
--kk increments if number is divisible by 15 i.e., number is Zoom--
ii=0;jj=0;kk=0;
for(j=0;j<2;j++)
{
cin>>num[j];
}
while(num[0]<=num[1])
{
if(num[0]%3==0 && num[0]%15!=0)
ii++;
if(num[0]%5==0 && num[0]%15!=0)
jj++;
if(num[0]%15==0)
kk++;
num[0]++;
}
cout<<ii<<" "<<jj<<" "<<kk<<endl;
}
cin>>t;
}
此代码对给定的示例输出有效 它不适用于以下给定的输入,即, 示例输入
3
1 961574729077486878
1 969690745985575352
2 932572744790738365
示例输出
256419927753996501 128209963876998250 64104981938499125
258584198929486760 129292099464743380 64646049732371690
248686065277530231 124343032638765116 62171516319382557
请指定合适的算法以减少程序的运行时间...从那以后 while循环在计算中花费了很多时间。
答案 0 :(得分:2)
你不应该迭代给定的范围,因为这太慢了。
让我们解决一个处理范围[1, x]
的简单问题:
在此范围内,有:
x / 3 numbers divisible by 3
x / 5 numbers divisible by 5
x / 15 numbers divisible by 15
现在你希望那些可被3
整除,但不能被15
整除,5
而不是15
,15
,你也想要推广它到范围[a, b]
。你应该可以从这里做到这一点。
答案 1 :(得分:2)
这里有一个数学捷径。您可以使用离散数学中的包含 - 排除原则来确定X,Y和Z的值。例如,让我们使用范围[10,100]来完成概念。
对于3:10/3 = 3和100/3 = 33.对于5:10/5 = 2和100/5 = 20.对于15:10/15 = 0和100/15 = 6。
请注意,您必须始终向下舍入整数。
现在,33-3 = 30,20-2 = 18,6和0 = 6.您知道Z的值为6,因为此范围内有6个数字可被15整除。但是, Y的值不是18.你必须考虑15可以被5整除,所以你需要减去数字Z. 18 - Z(6)= 12.同样适用于寻找X. 33 - Z(6 )= 27.因此,对于这个例子,答案是X = 27,Y = 12,Z = 6.
作为一般情况,以下是您需要做的事情:
将每个因子(3,5和15)除以范围的下限并保存这些值,始终向下舍入到最接近的整数。然后将每个因子除以范围的上限,再次向下舍入到最接近的整数。减去这些值以获得可被这些数字整除的范围内的数字量。然后记住一些数字正在计数两次,从zoom和bah中减去zoombah的值。这将为您提供正确的答案。
编辑:在查看其他答案后,我意识到您还必须检查以确保您的下限不能完全被因子整除。如果是这种情况,那么你必须在你的“在范围内被X整除的数字的数量”中加1。
答案 2 :(得分:1)
x
n/x
从1到n整除的元素数量
通过
查找从a
到b
(包括)可被3整除的元素数量
b/3 - a/3
但如果a可以被整除3,那么你会少一个。所以将a
减少1
a1=b/3 - (a-1)/3;
a2=b/5 - (a-1)/5;
a3=b/15 - (a-1)/15;
// To remove numbers divisible by 3 and 15
a1=a1-a3;
// To remove numbers divisible by 5 and 15
a2=a2-a3;
cout<<a1<<" "<<a2<<" "<<a3<<endl;