码迷,mamicode.com
首页 > 其他好文 > 详细

递归+解析 SRM 593 Division Two - Level Two: WolfDelaymaster

时间:2015-08-18 22:44:15      阅读:190      评论:0      收藏:0      [点我收藏+]

标签:

WolfDelaymaster


Problem Statement

Wolf Sothe is playing the game Delaymaster. In this game, he can create new words according to the following rules:
  1. For each positive integer n, the string which consists of n copies of ‘w‘, then n copies of ‘o‘, then n copies of ‘l‘, and finally n copies of ‘f‘ is a valid word.
  2. The concatenation of two valid words is a valid word.
  3. Only the words that can be obtained by rules 1 and 2 are valid. There are no other valid words.
Thus, for example:
  • By rule 1, "wolf", "wwoollff", and "wwwooolllfff" are valid words.
  • Then, by rule 2, "wolfwwoollff" is a valid word.
  • By applying rule 2 twice, "wolfwwoollffwolf" is a valid word.
  • The string "wfol" is not a valid word (order matters).
  • The string "wwolfolf" is not a valid word (we can only concatenate, not insert one word into another).
  • The string "wwwoolllfff" is not a valid word (only two ‘o‘s instead of three).
You are given a String str. Return "VALID" if str is a valid word and "INVALID" otherwise. Note that the return value is case-sensitive: you must return the strings "VALID" and "INVALID" in all-uppercase.

Definition

  • ClassWolfDelaymaster
  • Methodcheck
  • Parametersstring
  • Returnsstring
  • Method signaturestring check(string str)
(be sure your method is public)

Limits

  • Time limit (s)2.000
  • Memory limit (MB)64

Constraints

  • str will contain between 1 and 50 characters, inclusive.
  • Each character in str will be ‘w‘, ‘o‘, ‘l‘ or ‘f‘.

Test cases

    • str"wolf"
    Returns"VALID"
    The first valid word from the examples in the problem statement.
    • str"wwolfolf"
    Returns"INVALID"
    The second invalid word from the examples in the problem statement.
    • str"wolfwwoollffwwwooolllfffwwwwoooollllffff"
    Returns"VALID"
    • str"flowolf"
    Returns"INVALID"

We can see this one as a standard recursive problem or as a parsing problem.

Recursion

Let us redefine a valid string as a concatenation between a valid string and a string that follows the pattern: ww...woo...oll...lff...f . The most complicated valid example case is:

wolfwwoollffwwwooolllfffwwwwoooollllffff

"wolfwwoollffwwwooolllfff" is a valid string and "wwwwoooollllffff" follows the repeated pattern.

Let us define f(s) as a function that returns true if and only if the string s is valid. We know that it must end with a string that follows the repeated pattern. It is easy to generate a string of 4r characters that follows the pattern, where r is positive. (For example, for r=2: wwoollff. For each r|s|, we can determine if the string ends with a repeated pattern string. Then we just need to check if the first |s|?4rcharacters of the string make a valid string. This is the same as calling f(s), where s is the string that is composed of the first |s|?4rcharacters of the string. If there is a repeated pattern AND the remaining string is also valid then the complete string is also valid.

We need a base case, eventually the string will be a single repeated pattern, which will make the remaining string the empty string. We can consider the empty string valid.

Note that each instance of f(s) calls at most one other instance of f(s) in which s is strictly smaller. E.g: If the string finishes with ‘wolf‘ it cannot finish with ‘wwoollff‘. We don‘t need memoization to make it run in time and it wouldn‘t really be dynamic programming to fill it iteratively.

class WolfDelaymaster:
 def check(self, s):
     
    # function returns w (r times) o (r times) l (r times) f (r times): 
    def wolf(r):
        return ''.join( ch * r for ch in "wolf" )
         
    if s == '':
        return "VALID"
     
    r = 1
    while 4 * r <= len(s):
        # s[-4*r:] equals the last 4*r characters in the string
        if wolf(r) == s[-4*r:] :
            return self.check( s[ :-4*r] ) #recurse 
            # s[-4*r:] equals the other characters 
        r += 1
         
    # if we didn't find any repeated pattern, it is invalid:
    return "INVALID"

String parsing

We can also try to just parse the string following the rules until we find a mistake.

  • We know that the string must start with w. If that is not the case, then the string is invalid.
  • Count the number of initial ws, let it be r. The following letters must be r ‘o‘ characters, then r ‘l‘ characters and r ‘f‘ characters.
  • After finding the f characters, restart over, the next character must be w, count the number of w and repeat until we find the end of string until a valid f character.

The code is more complicated but it works:

string check(string str)
{
    int i = 0;
    int len = str.length();
    while ( i < len ) {
        if (str[i] != 'w') {
            return "INVALID";
        }
        int r = 0;
        // Count the number of times w repeats as we move the pointer (i):
        while ( (i < len) && (str[i] == 'w') ) {
            r++;
            i++;
        }
        // repeat for o, l and f: (in that order):
        char chars[3] = { 'o', 'l', 'f' }; 
        for (char ch: chars) {
            // repeat r times:
            for (int k = 0; k < r ; k++) {
                // next character must a) exist b) be equal to ch
                if ( (i >= len) || ( str[i] != ch) ) {
                    return "INVALID";
                }
                // move pointer:
                i++;
            }
        }
    }
    return "VALID";
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

递归+解析 SRM 593 Division Two - Level Two: WolfDelaymaster

标签:

原文地址:http://blog.csdn.net/acm_10000h/article/details/47761173

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!