수학

진수와 진법

  • 숫자로 구성된 문자열을 N진법에 맞게 변환하기 위해서는?


진법 - 예제

  • A ** B % C 하게되면, 시간복잡도는 O(B)가 되어 시간이 초과된다.
  • 이진수를 활용하여 시간 복잡도를 줄인다.
  • 거듭제곱은 거듭제곱간의 곱으로 표현 가능

// 1. mod를 하면서 연산 ( 더 빠름 )
// 수를 mod로 미리미리 나누어주는게 연산이 더 빠르다. 
def pow_custom(a, b, mod):
   ret = 1
   while b :
     if b % 2 == 1 : ret = ret * a % mod
     a = a * a % mod
     b //= 2
   return ret

// 2. 총 결과를 mod하여 리턴
def pow_custom(a, b, mod):
   ret = 1
   while b :
     if b % 2 == 1 : ret *= a
     a *= a
     b //= 2
   return ret % mod

최대공약수와 최소공배수

  • 최대공약수
    • 공통적인 약수 중 최댓값 최대공약수가 1이면 서로소
  • 최소공배수
    • 공통된 배수 중 최소값
  • LCM(A,B) = A * B/GCD(A,B)
  • GCD만 잘 구한다면 LCM은 O(1)에 구할 수 있다.

최대공약수

// 1부터 체크
// 시간복잡도 : min(a,b)
def gcd(a, b):
 ret = 0
 for i in range(min(a, b)):
   if a % i == 0 and b % i == 0:
   ret = i
 return ret

// min(a,b) 부터 체크 - 더 빠름
// 시간복잡도 : O(1)
def gcd(a, b):
 for i in range(min(a, b), 0, -1):
   if a % i == 0 and b % i == 0:
 return i

유클리드 호제법

  • GCD(A,B) = GCD(B,A%B)
// a가 b의 배수일 때는 작은수가 최대공약수 이므로 b를 반환하고, 나누어 떨어지지 않는다면 뒷단계를 진행한다.
def gcd(a, b):
 	return b if a%b==0 else gcd(b, a%b)

소인수분해

// 2부터 N-1까지 체크
// 시간복잡도 : O(N)
def isPrime(N):
 for i in range(2, N):
 	if N % i == 0 : return False
 return True
 
 // 2부터 sqrt(N)까지 체크
 // 시간복잡도 : O(sqrt(N)) - 루트N
 def isPrime(N):
 i = 2
   while i*i <= N:
     if N % i == 0: return False
     i += 1
 return True

에라토스테네스의 체

  • 1은 소수가 아니니 1만 지운다.
  • 2는 소수이니, 2의 배수를 모두 지운다.
  • 3은 소수이니, 3의 배수를 모두 지운다.
  • 4는 소수가 아니니 4만 지운다.
  • 5는 소수이니, 5의 배수를 모두 지운다.
  • N까지의 소수를 구하기 위해서는 sqrt(N)까지 소수를 이용하면 가능하다.

//시간복잡도 - O(loglogN)
def era(N):
   ck, p = [False for _in range(N+1)], []
   for i in range(2, N+1):
     if ck[i] == True : continue // 지워지지 않은 경우
     p.append(i)
     for j in range(i*i, N+1, i):
     	ck[j] = True
   return ck, p

분할정복 (Divide & Conquer)

  • 문제를 분해할 수 있어야 한다.
  • 재귀함수 사용

하노이탑

https://www.mathsisfun.com/games/towerofhanoi.html

 

Play Tower of Hanoi

Tower of Hanoi Object of the game is to move all the disks over to Tower 3 (with your mouse). But you cannot place a larger disk onto a smaller disk.

www.mathsisfun.com


  • 마지막 판이 움직이기 위해서는 나머지 모든 판이 한 기둥에 있어야 한다.
  • 그렇다면 N개의 판 중 N-1개의 판을 기둥 2에 보내는 것이 우선이다.
  • N번째 판을 3번 기둥에 보내고
  • N-1개의 판을 다시 3번 기둥에 보낸다.
  • 1번 기둥 -> 2번 기둥의 과정과 2번 기둥 -> 3번 기둥의 과정은 같다.
  • F(N) = 2 * F(N-1) + 1
  • F(1) = 1

def hanoi(st, ed, sz): //start , end , size
     if sz == 1: return print(st, ed)
     hanoi(st, 6-st-ed, sz-1) // 6-st-ed - 중간기둥의 번호
     print(st, ed)
     hanoi(6-st-ed, ed, sz-1)
     
n = int(input())
print(2**n-1)
hanoi(1, 3, n)
  • 재귀함수 설계 시 최소 조건 / 탈출 조건 (sz==1) 을 분명하게 지정해야 한다.

'Algorithm > basic' 카테고리의 다른 글

grape/tree/heap/bst  (0) 2021.07.22
stack/queue/deque  (0) 2021.07.22
sort (select/bubble/quick/merge/radix)  (0) 2021.07.22
읽기와 분석 (시간복잡도/공간복잡도 등)  (0) 2021.07.15

+ Recent posts