Problem:
The Maya password is a string of passwords consisting of 0, 1, and 2. If a string of numbers contains 2012, the last day can be unlocked. Given a string consisting of 0, 1, and 2, only adjacent numbers can be exchanged. Find out how many conversions can be used to obtain the Maya password and give the password.
Ideas:
After a long time of trying, I gave up the idea of piecing together 2012 at a time. Instead, I used preprocessing to get the parts that match the Maya password in the range of all numbers, and then recursively traversed the given number string, obtain all possible transformations of the string and compare the number of steps required for each transformation result.
import sys def find_all_transfers(str): result={} if len(str) == 0: result[str] = 0 for index in range(0, len(str)): first=str[index] next_str=str[0:index] + str[index+1:len(str)] next_result=find_all_transfers(next_str) #print("next_result is: ") #print(next_result) for key in next_result: steps = index+next_result[key] if first+key not in result or steps < result[first+key]: result[first+key] = steps return result def build_map(): map={} for i in range(0, 3**13-1): if check_2012(i): map[i] = True return map def check_2012(number): while number >= 59: if number%81 == 59: return True number /= 3 return False def from_3_to_10(str): count=0 iterator = range(0, len(str)) for i in iterator: count+=int(str[-i-1])*(3**i) return count map = build_map() #print(map) str=raw_input("input string from 0,1,2: ") print("str is %s"%str) result = find_all_transfers(str) #print(result) min = sys.maxint min_key = "" for key in result: number = from_3_to_10(key) #print("value of %s is %d"%(key, number)) if check_2012(number): #print("min is %d"%min) #print("result[key] is %d"%result[key]) if min > result[key]: min = result[key] min_key = key print("min steps is %d, final string is %s"%(int(min), min_key))
Convert the number string to the 2012 Maya Password