파이선 ¶
파이선으로 재귀호출을 한번 구현해보았으나, 엄청 느리다.
~cpp
def TreeNPlusOne(aNumber):
print aNumber,
if aNumber == 1:
return
elif aNumber%2 == 0:
aNumber /= 2
else:
aNumber = 3*aNumber+1
TreeNPlusOne(aNumber)
알고리즘 ¶
1. 22의 경우 22, 11, 34...이렇게 되는데 22의 싸이클 안에 11, 34등의 싸이클도 포함되니 최대값에서 그들을 배제하는 것이 가능하다.
2. 범위 안에 어떤수의 2의 배수가 있는 경우(또는 (x - 1)/3이 있는 경우) 1과 같은 이유로 그 수는 최대값에서 배제한다.
2. 범위 안에 어떤수의 2의 배수가 있는 경우(또는 (x - 1)/3이 있는 경우) 1과 같은 이유로 그 수는 최대값에서 배제한다.
범위(Range)를 인위적으로 줄여야한다는 결론에 도달.
소스 ¶
~cpp
def TreeNPlusOne(aNumber, aMin, aMax, aBinaryMap):
count = 1
while(aNumber != 1):
if(IsInRange(aMin, aMax, aNumber) and aBinaryMap[aNumber-aMin]):
aBinaryMap[aNumber-aMin] = False
if(aNumber%2 == 0):
aNumber = aNumber/2
else:
aNumber = aNumber*3+1
count = count + 1
return count
def InputRange():
min, max = input('최소, 최대: ')
while IsCorrectInput(min, max) == False:
min, max = input('최소, 최대: ')
return min, max
def MakeBinaryMap(aMin, aMax):
rangeOfMap = aMax - aMin + 1
binaryMap = range(rangeOfMap)
for i in range(rangeOfMap):
binaryMap[i] = True
return binaryMap
def FindMaxCycleLength(aMin, aMax, aBinaryMap):
maxCycleLength = 0
for i in range(aMin, aMax+1):
if(aBinaryMap[i-aMin]):
cycleLength = TreeNPlusOne(i, aMin, aMax, aBinaryMap)
if(maxCycleLength < cycleLength):
maxCycleLength = cycleLength
return maxCycleLength
def OutputResult(aMin, aMax, aMaxCycleLength):
print aMin, aMax, aMaxCycleLength
def IsInRange(aMin, aMax, aNumber):
if(aMin <= aNumber and aMax >= aNumber):
return True
else:
return False
def PreInspection(aMin, aMax, aBinaryMap):
for i in range(aMin, aMax/2+1):
tempI = i
while(IsInRange(aMin, aMax, 2*tempI)):
aBinaryMap[tempI-aMin] = False
tempI = 2*tempI
def IsCorrectInput(aMin, aMax):
if(aMin > 0 and aMax < 1000000 and aMin < aMax):
return True
else:
print 'Not Accept'
return False
if __name__ == '__main__':
min, max = InputRange()
binaryMap = MakeBinaryMap(min, max)
PreInspection(min, max, binaryMap)
OutputResult(min, max, FindMaxCycleLength(min, max, binaryMap))










