我有2种转换器方法如下:
private const decimal MaxValidValue = 99.99m;
public decimal ConvertABToC(decimal a, decimal b)
{
return a * b;
}
public void ConvertCtoAB(decimal c, ref decimal a, ref decimal b)
{
if (c > MaxValidValue*MaxValidValue)
{
throw new ApplicationException();
}
if (c <= MaxValidValue)
{
a = 1.00m;
b = c;
}
else
{
// need to introduce some logic or assumptions here
}
}
有三件重要的事情要知道:
1)a和b变量的范围为0.00到99.99,因此c的值不能大于99.99 * 99.99
2)a,b和c的小数进动不得超过2小时,例如a = 99.123无效。
3)你可以使用舍入,只要你需要十进制.Round(a * b,2)== c。
4)如(1,3),(3,1),(2,2),(1,4),(0.5,8)或偶数(0.25,16)的组合都是有效的;只要c是a和b的乘积就没关系。
您将如何完成ConvertCtoAB的实施?
非常感谢,
答案 0 :(得分:2)
将C
乘以10,000。然后将这个数字计入其主要因素。然后找到素数因子的分区为两组,使得每组中数字的乘积小于10,000。如果可以找到这样的分区,则将这两个产品除以100 A
和B
。否则,请在号码中添加一个,然后重试。
例如,如果C=100.07
,则因子为2, 2, 5, 5, 10007
。由于其中一个产品必须包含因子10007
,这是一个素数,因此永远不能满足第一个条件。所以我们再次尝试使用1000701 = 3*3*3*13*2851
。这一次,我们可以对数字进行分区,我们将A=3.51
和B=28.51
作为可能的解决方案。
你最多可以做99次。如果您需要100或更多,则无法从ConvertABToC
生成输入值。
这只能保证ConvertCtoAB
的结果反馈到ConvertABtoC
时会生成相同的C
,而不是相反。{{1}}它似乎违反了规则#3,但其他地方的问题是关于四舍五入。
如果根本不允许进行舍入,则应在尝试原始10000 * C后停止并报告不可行性。
答案 1 :(得分:1)
我删除了之前的答案,因为我认为它不再有用,因为随着时间的推移,这个问题发生了很大的变化。
以下是我理解的问题:
您将获得c
类型的输入(decimal
),以便:
0 <= c <= 99.99m * 99.99m
c
最多包含两位小数(即c == decimal.Round(c, 2)
)您需要找到decimal
值a
和b
,以便:{/ p>
a
和b
中的每一个都在[0, 99.99m]
a
和b
各占最多两位小数decimal.Round(a * b, 2) == c
我的回答是c
的所有值都不能 。反例:c = 9997.50
a
和b
的最高可能值(每个99.99米)会产生decimal.Round(a * b, 2) == 9998.00
,因此产品太高会失败。
现在,如果你保持a
尽可能高,并尽可能减少b
,我们会得到a=99.99m, b=99.98m
- 现在decimal.Round(a * b, 2) == 9997.00
,这样就失败了产品太低了。
无法在这两个值之间获取任何产品 - 我们以尽可能少的数量扰乱了我们的第一次尝试。因此,a
和b
没有满足此问题的值。
(我期待引入一条新的规则来解决这个问题,因为这似乎是这个问题的方式......)
答案 2 :(得分:0)
Skeet将区间视为自身* 100的想法使得一切都变得更加清晰......
问题确实没有完整的解决方案。它要求你创建一个双射函数f:A x B - &gt; C,
其中A = B = {0 ... 9999}且C = {0 ... 9999 * 9999}
9999 * 9999 = 9998001;再加上0,它的基数为99,980,002。
A X B的基数为100,000,000。
当域和codomain具有不同的基数时,无法定义有限集上的双射函数。总共最多有19,998个c值,其(a,b)分解将有多个解决方案。
回到原始区间定义:最接近正确功能的是:
public decimal Ab2C(decimal a, decimal b)
{
if(a != 99.99 and a != 99.98)
return a*100 + b;
return (100-a)*100 + b; // for instance;
}
在这种情况下,0.02到99.97之间的值将给出独特的结果; a = 0.00或99.99将是相同的,同样对于a = 0.01或99.98。这两个值之间没有任何可能的区别。
public void C2AB(decimal c, out decimal a, out decimal b)
{
// todo: sanity checks.
if (c <= 99.99) // either a = 0.00, or a = 99.99; and b = c.
{
b = c;
a = 0.00;
return;
}
if (c <= 2*99.99)
{
b = c - 99.99;
a = 0.01; // or 9.98.
return;
}
a = c / 100;
b = c % 100;
}
}