기타 풀이

Sawol·2021년 3월 26일
0

algorithm & data structure

목록 보기
16/18
post-thumbnail

❗️ 계속해서 업데이트 될 예정...

잘못된 부분이 있다면 알려주세요 🙏


문제 10808

✏️ 내가 작성한 코드

import string
arr = [0]*26
alp = list(string.ascii_lowercase)
s = input()
for i in s:
    arr[alp.index(i)] += 1

for p in arr:
  print(p, end = ' ')

for문이 두 번 돌아가는게 아쉬워서 다른 방법을 찾아봤다.

import string
alp = list(string.ascii_lowercase)
s = input()
for i in range(26):
    print(s.count(alp[i]), end=' ')

count
count를 사용하면 for문을 한번 사용할 수 있다.
count는 시퀸스 형(list, 튜플 등)에서 특정 요소의 개수를 출력해준다.
Reference


문제 10808

✏️ 내가 작성한 코드

import string
arr = [-1]*26
alp = list(string.ascii_lowercase)
s = input()
for i in range(len(s)):
    arr[alp.index(s[i])] = s.index(s[i]) 

for p in arr:
    print(p, end = ' ')

💡 흥미로운 코드

import string
alp = list(string.ascii_lowercase)
s = input()
for i in alp:
    print(s.find(i), end = ' ')

find
문자열에 등장한 가장 작은 인덱스를 반환해줌.
값이 없으면 -1을 반환해준다.
Reference


문제 10820

✏️ 내가 작성한 코드

import sys
import string
s_list = map(lambda x: x.strip('\n'),sys.stdin.readlines())

for s in s_list:
    print(sum(i.islower() for i in s), end =' ')
    print(sum(i.isupper() for i in s), end =' ')
    print(sum(i.isdigit() for i in s), end =' ')
    print(sum(i.isspace() for i in s))

islower
문자열에 알파벳 소문자가 존재하는 지 boolean형식으로 나타냄.
isupper
문자열에 알파벳 대문자가 존재하는 지 boolean형식으로 나타냄.
isdigit
문자열에 숫자가 존재하는 지 boolean형식으로 나타냄.
isspace
문자열에 공백이 존재하는 지 boolean형식으로 나타냄.
Reference


문제 2743

✏️ 내가 작성한 코드

import string
s = input().lower()
print(sum(i.islower() for i in s))

lower()
문자열을 소문자로 바꿔줌.
upper()
문자열을 대문자로 바꿔줌.


문제 11655

✏️ 내가 작성한 코드

import string
s = input()
alp = list(string.ascii_lowercase)
for i in s:
    if i.islower() == True: # 소문자라면
        idx = alp.index(i)
        if idx >= 13:
            idx -= 13
            print(alp[idx], end='')
        else:
            print(alp[idx+13], end='')
    elif i.isupper() == True: # 대문자라면
        idx = alp.index(i.lower())
        if idx >= 13:
            idx -= 13
            print(alp[idx].upper(), end='')
        else:
            print(alp[idx+13].upper(), end='')
    else:
        print(i, end='')

문제 10824

✏️ 내가 작성한 코드

A, B, C, D = input().split()
print(int(A+B)+int(C+D))

문제 11656

✏️ 내가 작성한 코드

s = input()
result = sorted([s[i:] for i in range(len(s))])
for p in result: print(p)

문제 1158

✏️ 내가 작성한 코드

N, K = map(int, input().split())
circular = [str(i+1) for i in range(N)]
idx = 0
result = []
for t in range(N):
    idx += K-1
    idx %= len(circular)
    result.append(circular.pop(idx))
print('<', ', '.join(result), '>', sep='')

문제 10430

✏️ 내가 작성한 코드

A, B, C = map(int, input().split())
print((A+B)%C, ((A%C)+(B%C))%C, (A*B)%C, ((A%C)*(B%C))%C, sep = '\n')

문제 2609

✏️ 내가 작성한 코드

import math
a, b = map(int, input().split())
print(math.gcd(a,b), math.lcm(a,b), sep ='\n')

math
파이썬에서 수학과 관련된 라이브러리이다.
이 중 최소공배수와 최대공약수도 쉽게 구할 수 있는데, 원래 최소공약수만 지원을 해줘서 최소공배수는 a*b//최소공약수로 구했어야 했다.
하지만 파이썬 3.9 버전부터는 lcm을 이용해 간단히 구할 수 있다.
Reference


문제 1934

✏️ 내가 작성한 코드

import math
import sys

N = int(input())
for _ in range(N):
    a, b = map(int,sys.stdin.readline().split())
    print(math.lcm(a,b))

문제 1850

✏️ 내가 작성한 코드

import math

a, b = map(int, input().split())
for _ in range(math.gcd(a,b)): print(1, end='')

최대공약수를 구해, 그 수만큼 1을 출력하면 되는 문제이다.


문제 9613

✏️ 내가 작성한 코드

import sys
import math
import itertools

t = int(input())
for _ in range(t):
    _, *arr = map(int, sys.stdin.readline().split())
    comb = list(itertools.combinations(arr,2))
    print(sum(math.gcd(i[0], i[1]) for i in comb))

파이썬에서의 _의 의미
사용하지 않는다는 의미. 하나의 '약속'임.
a, *b = [1, 2, 3, 4]의 의미
시퀸스 자료형이 주어진 상태에서 *이 있는 경우는 정의되지 않은 나머지 요소들을 *이 있는 변수에 할당한다는 의미.
여기서는 a=1, b=2,3,4를 갖는다.


문제 11005

✏️ 내가 작성한 코드

N, B = map(int, input().split())
value = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
result = ''
while N:
    result += value[N%B]
    N //= B
print(result[::-1])

숫자 N을 B진법으로 나타내고 싶을 때는 N을 B로 나눈 나머지를 모두 합친 뒤 이를 뒤집어 줘야함.


문제 2745

✏️ 내가 작성한 코드

N, B = input().split()
B = int(B)
value = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
result = 0
for i, v in enumerate(N[::-1]):
    result += value.index(v)*B**i
    
print(result)

enumerate
시퀸스형의 데이터에서 인덱스와 값을 함께 반환해줌.
보통 for문과 함께 사용됨.


문제 1373

✏️ 내가 작성한 코드

n = int(input(), 2)
print(format(n, 'o'))

n진수를 10진수로 변환
int(value, n)을 쓰면 value 값이 n진수로 바뀐다.
다만, 이때 valuestring이여야한다.

value를 n진수로 변환
format(value, n)를 사용하면 value 값이 n진수로 바뀐다.
이때, value 값은 int형이여야하고, n은 'o'의 경우 8진수, 'b'의 경우 2진수를 의미하며, '#o'와 같이 앞에 #을 붙이는 경우 0x11과 같이 접두어가 붙는다.


문제 2089

✏️ 내가 작성한 코드

v = int(input())
result = ''
while v:
  if v%(-2):
    result += '1'
    v = v//-2 + 1
  else:
    result += '0'
    v //= -2
print(result[::-1])

문제 11576

✏️ 내가 작성한 코드

A, B = map(int, input().split())
m = int(input())
v = list(map(int, input().split()))
result = 0
answer = []
for idx, number in enumerate(v[::-1]):
    result += number*(A**(idx))
while result:
    result, r = divmod(result, B)
    answer.append(str(r))
print(' '.join(answer[::-1]))

A진법으로 표기된 숫자를 10진법으로 바꾼 뒤 다시 B진법으로 바꾸는 방식.


문제 1978

✏️ 내가 작성한 코드

import math

N = int(input())
arr = [i for i in range(1001)]
arr[0], arr[1] = False, False
num_list = list(map(int, input().split()))
for i in range(2, int(math.sqrt(1000))+1):
    if arr[i] != False:
        j = 2
        while j*i <= 1000:
            arr[j*i] = False
            j += 1
            
print(len([i for i in num_list if arr[i]]))

소수
2보다 큰 자연수 중 1과 자기 자신을 제외한 다른 자연수로 나누어 떨어지지 않는 수.

에라토스네테스의 체
소수를 빠르게 판별할 수 있는 알고리즘.
시간 복잡도가 O(NloglogN)으로 매우 빠름.
하지만 공간 복잡도가 O(N)임.
아래 그림처럼 소수의 배수들을 모두 제거하는 방식으로 구현함.

Reference


문제 1929

✏️ 내가 작성한 코드

import math

M, N = map(int, input().split())
arr = [i for i in range(N+1)]
arr[0], arr[1] = False, False
for i in range(2, int(math.sqrt(N))+1):
    if arr[i] != False:
        j = 2
        while i*j <= N:
            arr[i*j] = False
            j += 1

for i in arr[M:]:
    if i != False:
        print(i)

에라토스네테스의 체 알고리즘 풀이


문제 6588

✏️ 내가 작성한 코드

import math
import sys

num_list = list(map(int, sys.stdin.readlines()))
arr = [i for i in range(1000000+1)]
arr[:2] = False, False
for i in range(2, int(math.sqrt(1000000))+1):
    if arr[i] != False:
        j = 2
        while i*j <= 1000000:
            arr[i*j] = False
            j += 1

for i in num_list[:-1]:
    for p in range(i+1):
        if arr[p] and arr[i-p]:
            print(f'{i} = {arr[p]} + {arr[i-p]}')
            break
        if p == i//2:
            print("'Goldbach's conjecture is wrong.")

에라토스네테스의 체 알고리즘을 사용했는데 자꾸 시간초과가 떴다.
1000000의 경우의 수를 다 구하는 것 때문인가 싶어 앞에 코드만 주구장창 고쳤다. 그러다 혹시 뒤에 더해서 n이 되는 홀수 값을 짜는 부분에서 시간 초과가 뜨는건가 싶어서 코드를 수정해봤다. arrreverse해서 서로 비교하게 했는데 이 코드가 시간이 오래 걸린거 같다. 위 코드로 수정하니 성공했다.
참고로 홀수를 찾는 알고리즘은 n0을 기준으로 같은 거리만큼 떨어진 소수를 찾으면 된다.


문제 6588

✏️ 내가 작성한 코드

N = int(input())
s = 2
while N != 1:
    if N % s == 0:
        print(s)
        N //= s
    else:
        s += 1

문제 10872

✏️ 내가 작성한 코드

N = int(input())
result = 1
for i in range(1, N+1):
    result *= i
print(result)

문제 1676

✏️ 내가 작성한 코드

N = int(input())
print(N//5 + N//(5**2) + N//(5**3))

팩토리얼중 5의 배수가 몇개 들어갔는지 count하면 된다.
다만, 5의 제곱, 세제곱...N제곱에서는 5가 두 번 들어가는 꼴이므로 더해줘야한다. 문제에서는 N이 최대 500이기때문에 3제곱까지만 구한다.


문제 1024

✏️ 내가 작성한 코드

N, L = map(int, input().split())

for i in range(L, 101):
    x = (N/i -(i+1)/2)
    if x == int(x):
        if x < -1:
            break
        else:
            for j in range(1, i+1):
                print(int(x)+j, end = ' ')
            exit()
        
print(-1)

N = (x+1) + (x+2) + ... + (x+L) 이다. 이 식을 조금 더 간단하게 정리하면 N = Lx + L(L+1)/2이다. x를 구하는 것이 목표이니 식을 조금 바꿔본다.
Lx = N - L(L+1)/2 즉, x = N/L -(L+1)/2이다.
문제에서 x+1은 정수라고 하니, 만약 x+1이 정수이면 리스트를 완성해서 출력하면 된다. 다만 음의 정수면 -1을 출력해야한다.
이전에도 느꼈지만, 중 고등학생때 배운 수학을 다 까먹은거같다. 여유가 생기면 중,고등 수학을 다시 공부해야겠다.

0개의 댓글