TopCoder算法问题 - 如何在这个上取得进展?

时间:2010-07-19 21:23:13

标签: algorithm language-agnostic

我最近加入了TopCoder,过去几天一直在练习室练习。我遇到了这个我似乎无法解决的问题。任何帮助将不胜感激。

问题

  

字符串的产品价值是   所有数字的产品('0' - '9')in   字符串。例如,产品   值“123”是1 * 2 * 3 = 6   字符串被称为彩色,如果它   仅包含数字和产品   每个非空的价值   连续的子串是不同的。

     

例如,字符串“263”有六个   子串:“2”,“6”,“3”,“26”,“63”   和“263”。这些产品的价值   子串是:2,6,3,2 * 6 = 12,6   * 3 = 18和2 * 6 * 3 = 36。全部六款产品   值是不同的,“263”是   丰富多彩。

     

另一方面,“236”不是   多彩,因为它的两个   子串,“6”和“23”,有   相同的产品价值(6 = 2 * 3)。

     

返回第k个(基于1)   按字典顺序排列最小的彩色   长度为n的字符串。如果少了   比k长度为n的彩色串,   返回一个空字符串。

我的方法

我们不能将'0'和'1'作为n中的数字。 所有数字必须是不同的。首先,n应该小于9.(只能使用数字2,3,4,5,6,7,8,9,每个数字只能使用一次)。

因为我们知道,我们可以从“23”(最小的2位彩色字符串)开始作为基本字符串并添加一个允许的数字(检查字符串是否仍然是彩色的,每次添加时)直到我们达到长度n。

一旦我们达到长度n,我们就可以用数字“玩”来找到最小的k。

我的问题

我觉得这种方法不够快。即使它是,我应该以什么系统的方式使用数字,这样我从最小的开始,并通过最小的kth?

如何使用此方法在此问题上取得进展?或者有更智能的方法来解决这些问题吗?

我不是要求任何解决方案或任何东西。我只想要一些线索和一些线索。

我在几秒钟内解决了一些问题,有些问题花了几个小时思考,有些像这样我无法做到。但我相信所需要的只是一些练习,但如果没有人带路,我就无法取得进步。

提前致谢=)

*顺便说一下,这个问题来自SRM 464 DIV 2 - 500pt。问题。所有版权归TopCoder所有。

4 个答案:

答案 0 :(得分:4)

Topcoder有一个论坛,他们为每个SRM创建一个帖子(464是here)。也许你的问题已在那里得到解答:)

答案 1 :(得分:2)

  

我觉得这种做法不够快。

为什么不呢?我甚至不打算对它“聪明”:你有8个数字,每个数字最多可以使用一次。总计数为8 * 7 + 8 * 7 * 6 + 8 * 7 * 6 * 5 + ... 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1 = 109592,这是一个快速的电脑要经过。

按字典顺序列举所有这些,并检查每一个以查看它是否“丰富​​多彩”。

答案 2 :(得分:2)

减少搜索空间的一种方法是考虑这一点:只有当第一个n字符给出的子字符串也是彩色的时,长度为n-1的字符串才可以是彩色的。这个断言是真的应该是相当明显的。

假设您有一个函数colorful(n),它返回长度为n的所有彩色字符串的集合。你可以递归地实现它,如下所示:

colorful(n):
  if n = 1:
    return { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" }

  def colorful_subs = colorful(n-1)
  def colorfuls

  for each sub in colorful_subs:
    remaining_digits = { 2, 3, 4, 5, 6, 7, 8, 9 } - digits_in(sub)

    for each digit in remaining_digits:
      if is_colorful(sub, digit):
        colorfuls += (sub + digit)

  return colorfuls

支持函数is_colorful可以利用以下事实:作为第一个参数给出的子字符串已知为彩色且不包含附加数字

然后调用colorful(n)并选择返回集的k元素。 (注意我们必须在基本情况下包含“0”和“1”,否则会给出n = 1)的错误答案

这基本上是dynamic programming方法。我确信这可以改进 - 可能有一种聪明的方法可以弄清楚如果将一个数字附加到一个彩色数字会使数字不再丰富多彩而不实际进行并检查。但这确实比2-9的所有可能排列检查的数字要少得多。

答案 3 :(得分:0)

这是一个快速的代码我放在一起,看起来像一个有趣的问题...... 我希望我没有误解这个问题。

干杯

    public class Colorful {


    /**
     * Find the k-th colorful number that has n digits
     * @param n The number of digits
     * @param k The k-th colorful position
     * @return  The colorful number 
     */
    public static String findColorfulNumber(int n, int k) {
        int start=(int) Math.pow(10, n-1);
        int end=(int) Math.pow(10, n);
        Stack<String> colorfulNumbers=new Stack<String>();
        for(int i=start;i<end;i++){
            String currentNumber=i+"";
            if(isColorful(currentNumber)){
                colorfulNumbers.push(currentNumber);
                if(colorfulNumbers.size()==k)
                    break;
            } 
        }

        return colorfulNumbers.size()==k?"":colorfulNumbers.pop();
    }

    /**
     * Checks if a given number is colorful
     * @param number    The number to check
     * @return  Returns <code>true</code> if the number is colorful, <code>false</code> otherwise
     */
    private static boolean isColorful(String number) {
        char[] numberAsArray = number.toCharArray();
        Set<Integer> uniqueProducts=new LinkedHashSet<Integer>();

        return generateUniqueNumbers(numberAsArray,1,uniqueProducts);
    }


    /**
     * Recursive function that checks whether a number is colorful or not
     * @param numberAsArray The number as an array
     * @param charCount The sequence size of a number of characters to check at a given recursive iteration, starts from 0 ends at array length... 
     * @param uniqueProducts    The set of unique products computed until current iteration 
     * @return
     */
    private static boolean generateUniqueNumbers(char[] numberAsArray, int charCount,
            Set<Integer> uniqueProducts) {

        if(charCount>numberAsArray.length)
            return true;

        for(int i=0;(i+charCount-1)<numberAsArray.length;i++){
            int product=1;
            for(int j=0;j<charCount;j++){
                product=product*Integer.parseInt(new String(numberAsArray[i+j]+""));
            }
            if(!uniqueProducts.add(product))
                return false;
        }
        return generateUniqueNumbers(numberAsArray,charCount+1,uniqueProducts);
    }
}