백준 15650번 N과 M(2) 문제

 

123116KB, 116MS로 해결

 

1부터 N까지 자연수 중 중복 없이 M개를 고른 수열의 집합

-> Combination (조합)

 

파이썬 라이브러리 itertools의 combinations을 이용하여 손쉽게 풀 수 있는 문제.

 

from itertools import combinations
n, m = map(int, input().split())
data = [i for i in range(1, n + 1)]
for i in combinations(data, m):
    for j in i:
        print(j, end=' ')
    print()

백준 1002번 터렛 문제

 

 

import math
for _ in range(int(input())):
    x1, y1, r1, x2, y2, r2 = map(int, input().split())
    distance = math.sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2)

    if distance == 0 and r1 == r2: # 합동
        print(-1)
    elif abs(r1 - r2) == distance or r1 + r2 == distance: # 내외접
        print(1)
    elif abs(r1 - r2) < distance < (r1 + r2): # 서로다른 두 점
        print(2)
    else:
        print(0)

 

수학 공식을 통해 풀 수 있는 문제.

 

 

백준 9020 골드바흐의 추측 문제

 

시간 초과의 굴레.....

 

 

처음에는 주어진 수를 2개의 중복순열로 리스트를 만들어

해당 리스트가 전부 소수로 되어있으면 추출하는 방식으로 했는데, 그 수많은 수들을 매 케이스마다 반복하려니

시간초과가 나왔다.

 

from itertools import product
import math
for _ in range(int(input())):
    target = int(input())
    array = [True for i in range(target + 1)]
    result = []

    for i in range(2, int(math.sqrt(target)) + 1):
        if array[i]:
            j = 2
            while i * j <= target:
                array[i * j] = False
                j += 1

    data = []
    for i in range(2, target + 1):
        if array[i]:
            data.append(i)

    result = []
    for i in product(data, repeat=2):
        if i[0] + i[1] == target:
            result.append(i)

    if len(result) % 2 == 0:
        index = len(result) // 2 - 1
        print(result[index][0], result[index][1])
    else:
        index = len(result) // 2
        print(result[index][0], result[index][1])

최초 코드

 

 

그래서 결국 처음에 에라토스테네스의 체로 구별해 낸 소수 리스트을 1회 이용하여 연산해야 할 방법을 찾아야 했다.

중간값부터 1씩 올리고 / 1씩 내리고 를 반복하며 찾아가는 방식으로 n/2 회로 시간 복잡도를 줄여나갔다.

 

import math, sys
input = sys.stdin.readline
array = [True for i in range(10001)]

for i in range(2, 101):
    if array[i]:
        j = 2
        while i * j <= 10000:
            array[i * j] = False
            j += 1

for _ in range(int(input())):
    target = int(input())
    x = target // 2
    y = x

    for _ in range(10000):
        if array[x] and array[y]:
            print(x, y)
            break
        x -= 1
        y += 1

결과 코드

 

백준 4948번 베르트랑 공준 문제

 

에라토스테네스의 체를 이용했던 문제와 유사하다.

체를 이용해 주어진 수의 범위를 n ~ 2n으로 설정하여 소수가 나올때마다 count를 올려주기만 하면 된다.

 

import math
import sys
input = sys.stdin.readline

start = 1
while True:
    start = int(input())
    if start == 0:
        break
    end = 2 * start
    count = 0

    if start == 1:
        print("1")
        continue

    array = [True for i in range(end + 1)]

    for i in range(2, int(math.sqrt(end)) + 1):
        if array[i]:
            j = 2
            while i * j <= end:
                array[i * j] = False
                j += 1

    for i in range(start + 1, end + 1):
        if array[i]:

            count += 1

    print(count)

+ Recent posts