解决了,对于我的问题的精确解决方案,请参阅我的回答
我对这个令人困惑的标题感到抱歉,让我澄清一下我的问题:
我的Java程序应该用百分比来问一个数学问题。
它应该以这种格式创建一个问题:
25% of 4616 = ?
要求是:
有没有快速方法可以找到满足最后要求的随机数?
我能想到的唯一解决方案是找到百分比,然后创建一个循环,在找到满足要求的随机数之前不会停止(在示例中直到number % 4 == 0
为真)
但是这个循环可以运行数千次,直到找到正确的数字。
我的问题有更好的方法吗?
修改 似乎我没有弄清楚我的问题是什么,我不希望结果是双数,只是整数。
例如:如果我的百分比是65%,那么可能的问题是
7620的65%=?
因为解4953也是整数。
我想找到一个介于100和9999之间的随机数,它是一个整数,并且在方程p * x = y中有一个整数。
答案 0 :(得分:1)
我只需选择一个百分比并从答案中向后工作即可得出问题:
p * x = answer | 0 < p < 100, p = 5k, 100 <= x < 10000
所以,选择你的百分比:
p = (5 * rand(1, 9)) / 100.0;
确保您的100 <= answer / p < 10000
:
answer = rand(100, p * 9999);
解决'未知':
x = p / y
答案 1 :(得分:1)
你是对的,分隔符取决于p
值。因此,首先选择p
,然后使用它来计算分隔符以选择范围内的随机数:
For 5% it should be dividable by 20 (5/100 = 1/20)
For 10% it should be dividable by 10 (10/100 = 1/10)
For 15% it should be dividable by 20 (15/100 = 3/20)
For 20% it should be dividable by 5 (20/100 = 1/5)
For 25% it should be dividable by 4 (25/100 = 1/4)
For 30% it should be dividable by 10 (30/100 = 3/10)
...
您可以通过减少分数p/100
并选择分母
以下答案不正确
看起来你必须从100-9999范围内选择可以分割20的数字。
answer = x * p/100 = x * k/20 (since p is dividable by 5)
k = rand(1,494)
x = 100 + 20*k
p = 5*rand(1,20)
答案 2 :(得分:1)
让p
为百分比(分子,即25%),x
除以初始值,y
为结果整数。
由于p
是一个百分比,是5的倍数,而0 to 100
,我们可以将其表示为p = 5a/100 = a/20
0 <= a <= 20
。
对于x
,我们的约束为100 <= x <= 999
。
首先选择满足a
的{{1}}。
接下来,我们选择0 <= a <= 20
。好吧,要使x
为整数结果,我们只需要20来除p * x = (a/20) * x
。好吧,我们知道a * x
(“20除以* x”)当且仅当
20 | (a * x)
由于我们有j = (a * x) / 20 (<- j is some integer)
<=> j = (a * x) / (2^2 * 5^1)
,我们可以用它的素因子化代替它:
a
现在意识到j = (p1^e1 * p2^e2 * ... * pn^en) * x / (2^2 * 5^1)
小于20,因此它的素数分解可能非常简单并且可能与素数分解“重叠”。例如,如果a
,则上述等式简化为
a = 5
在这种情况下,很容易看出我们如何生成j = x / 4
,它将产生一个整数x
(4的倍数。虽然你也需要j
!)。所以“重叠”(即分子中与分母相同的素因子)是超级有益的。这就是最大公约数出现的地方。 100 <= x <= 9999
是划分GCD(a, 20)
和a
的最大整数。 20
的素数因子化恰恰是重叠。它还有一个很好的属性,一旦我们“删除”重叠,结果值:
GCD
拥有j = b * x / c
和b
是互质的好房产。据我们所知,c
是一个整数,当且仅当b * x / c
。
所以让c | x
。然后根据定义,我们有GCD(a, 20) = k
和a/k = b
,所以20/k = c
。因此,让a/20 = b/c
x = c * m
为整数。然后我们有:
m
因此,我们可以100 <= m * c <= 9999
=> 100 / c <= m <= 9999 / c
制作您的floor(rand(100 / c, 9999 / c))
。
总结:
m
请注意,a = rand(0, 20)
p = 5*a
c = 20 / GCD(a, 20)
m = floor(rand(100 / c, 9999 / c))
x = c * m
y = (p / 100) * x
实际上是边缘情况,而且a = 0
不会给您完全均匀的分布。如果您需要覆盖这些内容,我可以考虑一下并稍微调整一下答案。此外,欧几里得算法实现起来很简单,你可以查阅它。哎呀,因为floor()
你可能只是对函数进行硬编码:)
修改我第一次忘记在摘要中定义a < 20
。这是一个例子,用于生成下面的反例:
c
在此示例中,我们a = 5
p = 25
c = 20 / GCD(5, 20) = 20 / 5 = 4
m = some integer in [25, 2500). In this case so we randomed 879
x = 3516
y = 879
很方便,因此结果是GCD(a, 20) = 5
,但情况并非总是如此。
答案 3 :(得分:0)
好的,感谢roliu我终于找到了解决方案。 这是我的最终解决方案的样子:
创建1到20之间的随机数(因为百分比可以按5分割):
a = rand(1,20)
找出最大公约数:
b = gcd(a,20)
创建一个范围除以20 / gcd的随机数(如果您不知道原因,请参见denis答案):
c = rand(floor(100/(20/b)),floor(9999/(20/b)))
将随机数乘以20 / gcd得到范围内的数字,我们的x:
x = floor(c * (20/b))
将数字乘以百分比以获得解决方案y:
y = floor(x * (a/20))
将百分比转换为要打印的正确值:
p = a * 5
最终等式:
p % of x = y