检测整数是否可以写为给定整数的倍数

时间:2010-06-21 02:23:46

标签: algorithm math

我有一组给定的整数:

A[] = { 2, 3, 4, 5, 6, 7, 8, 10, 15, 20, 25, 30, 40, 50, 100, 500 }
  1. 我想检查一个给定的整数T是否可以写成A[]中数字的倍数; 编辑澄清: A [] 中的任何数字都可以使用。如果使用的话只能使用一次。 EX 60是有效的T.60 = 30 * 2。 AlSO 90有效。 90 = 3 * 5 * 6

  2. 检查哪些数字可以形成整数T

  3. 如果数字T无法写为该数字的倍数,也会将 2个最接近的整数返回给定的T(可以这样写)。
  4. 第2部分和第3部分,如果有人帮我完成第1部分,我想我可以自己解决。

    我知道这是一个算法问题,甚至是数学问题,但如果有人可以提供帮助,请做。

    不是家庭作业。见下面的评论。

    解。 非常适合所有答案.1回答特别(但作者选择删除它,我不知道为什么,因为它是正确的。) Ty作者(不记得你的名字。)

    带有扭曲的解决方案代码(作者的算法多次使用一次乘法器。这个只使用乘数1次)

    int oldT = 0;
            HashMap<Integer, Boolean> used = new HashMap<Integer, Boolean>();
            while (T != 1 && T != -1) {
                oldT = T;
                for (int multiple : A) {
                    if (!used.containsKey(multiple)) {
                        if (T % multiple == 0) {
                            T = T / multiple;
                            used.put(multiple, true); 
                        }
                    }
                }
                if (oldT == T)
                    return false;
            }
            return true;
    

2 个答案:

答案 0 :(得分:3)

如果T不是很大(比如说,&lt; 10 ^ 7),这就是直接DP。

a[1] = true; // means that number '1' can be achieved with no multipliers
for (every multiplier x) {
   for (int i = T; i > 0; --i) {
      if (a[i] and (i * x <= T)) {
          // if 'i' can be achieved and 'x' is a valid multiplier,
          // then 'i * x' can be achieved too
          a[i * x] = true;
      }
   }
}

假设每个乘数只能使用一次 现在,你可以找到T的分解,如果你有另一个数组b [i]存储用于实现i的乘数。

如果您没有时间,有很多在线内容可以熟悉动态编程。它应该让你知道如何处理这些问题。例如,这个似乎不错 http://www.topcoder.com/tc?module=Static&d1=tutorials&d2=dynProg

答案 1 :(得分:1)

我不确定你在问什么。

如果用户可以选择n *(其中一个数字),那么请注意你有2个,3个,5个和7个素数,所以如果你的数字可以被2,3,5或7整除,那么把它分开,然后你有n *(那个)。

如果您必须将这些数字相乘,但可以多次相乘,那么请再次注意所有数字都会计入2,3,5和7的幂。检查下注是否可以被这些(将它们分开,直到你不能再分开,然后看看你是否留下1)并计算你除以每一个的次数。

如果你必须将数字相乘而不用替换,那么再次找到素数因子分解并从列表中删除哪个数字使得权力呈现最均匀。如果你设法删除所有倍数,那就完成了。

除了最后一种情况之外,可以下注的数字非常密集,因此您可以通过向上或向下并再次检查找到最近的数字。在最后一种情况下,搜索附近的东西可能有点棘手;假设用户不打赌2 * 3 * 4 * 5 * 6 * 7 * 8 * 10 * 15 *,你可能只想形成一个可能(低)投注的表并提出一些建议。