no image
[백준 1546번 문제, 파이썬3] 평균
문제 문제 세준이는 기말고사를 망쳤다. 세준이는 점수를 조작해서 집에 가져가기로 했다. 일단 세준이는 자기 점수 중에 최댓값을 골랐다. 이 값을 M이라고 한다. 그리고 나서 모든 점수를 점수/M*100으로 고쳤다. 예를 들어, 세준이의 최고점이 70이고, 수학점수가 50이었으면 수학점수는 50/70*100이 되어 71.43점이 된다. 세준이의 성적을 위의 방법대로 새로 계산했을 때, 새로운 평균을 구하는 프로그램을 작성하시오. 입력 첫째 줄에 시험 본 과목의 개수 N이 주어진다. 이 값은 1000보다 작거나 같다. 둘째 줄에 세준이의 현재 성적이 주어진다. 이 값은 100보다 작거나 같은 음이 아닌 정수이고, 적어도 하나의 값은 0보다 크다. 출력 첫째 줄에 새로운 평균을 출력한다. 실제 정답과 출력값의..
2023.05.14
no image
[백준 2577번 문제, 파이썬3] 숫자의 개수
문제 문제 세 개의 자연수 A, B, C가 주어질 때 A × B × C를 계산한 결과에 0부터 9까지 각각의 숫자가 몇 번씩 쓰였는지를 구하는 프로그램을 작성하시오. 예를 들어 A = 150, B = 266, C = 427 이라면 A × B × C = 150 × 266 × 427 = 17037300 이 되고, 계산한 결과 17037300 에는 0이 3번, 1이 1번, 3이 2번, 7이 2번 쓰였다. 입력 첫째 줄에 A, 둘째 줄에 B, 셋째 줄에 C가 주어진다. A, B, C는 모두 100보다 크거나 같고, 1,000보다 작은 자연수이다. 출력 첫째 줄에는 A × B × C의 결과에 0 이 몇 번 쓰였는지 출력한다. 마찬가지로 둘째 줄부터 열 번째 줄까지 A × B × C의 결과에 1부터 9까지의 숫자가..
2023.05.14
no image
[백준 3052번 문제, 파이썬3] 나머지
문제 문제 두 자연수 A와 B가 있을 때, A%B는 A를 B로 나눈 나머지 이다. 예를 들어, 7, 14, 27, 38을 3으로 나눈 나머지는 1, 2, 0, 2이다. 수 10개를 입력받은 뒤, 이를 42로 나눈 나머지를 구한다. 그 다음 서로 다른 값이 몇 개 있는지 출력하는 프로그램을 작성하시오. 입력 첫째 줄부터 열번째 줄 까지 숫자가 한 줄에 하나씩 주어진다. 이 숫자는 1,000보다 작거나 같고, 음이 아닌 정수이다. 출력 첫째 줄에, 42로 나누었을 때, 서로 다른 나머지가 몇 개 있는지 출력한다. 코드 print(len(set([i % 42for i in[int(input())for _ in range(10)]]))) 해결 먼저 10개를 숫자로 입력을 받고 그걸 42로 나눠서 set에 넣는다..
2023.05.14
no image
[백준 2475번 문제, 파이썬3] 검증수
문제 문제 컴퓨터를 제조하는 회사인 KOI 전자에서는 제조하는 컴퓨터마다 6자리의 고유번호를 매긴다. 고유번호의 처음 5자리에는 00000부터 99999까지의 수 중 하나가 주어지며 6번째 자리에는 검증수가 들어간다. 검증수는 고유번호의 처음 5자리에 들어가는 5개의 숫자를 각각 제곱한 수의 합을 10으로 나눈 나머지이다. 예를 들어 고유번호의 처음 5자리의 숫자들이 04256이면, 각 숫자를 제곱한 수들의 합 0+16+4+25+36 = 81 을 10으로 나눈 나머지인 1이 검증수이다. 입력 첫째 줄에 고유번호의 처음 5자리의 숫자들이 빈칸을 사이에 두고 하나씩 주어진다. 출력 첫째 줄에 검증수를 출력한다. 코드 import sys line = map(int, sys.stdin.readline().spl..
2023.05.14
no image
[백준 10809번 문제, 파이썬3] 알파벳 찾기
문제 문제 알파벳 소문자로만 이루어진 단어 S가 주어진다. 각각의 알파벳에 대해서, 단어에 포함되어 있는 경우에는 처음 등장하는 위치를, 포함되어 있지 않은 경우에는 -1을 출력하는 프로그램을 작성하시오. 입력 첫째 줄에 단어 S가 주어진다. 단어의 길이는 100을 넘지 않으며, 알파벳 소문자로만 이루어져 있다. 출력 각각의 알파벳에 대해서, a가 처음 등장하는 위치, b가 처음 등장하는 위치, ... z가 처음 등장하는 위치를 공백으로 구분해서 출력한다. 만약, 어떤 알파벳이 단어에 포함되어 있지 않다면 -1을 출력한다. 단어의 첫 번째 글자는 0번째 위치이고, 두 번째 글자는 1번째 위치이다. 코드 answer = [-1 for _ in range(26)] # 출력할 배열을 -1로 초기화 line =..
2023.05.14
no image
반복하지 않는 수, 중복되지 않는 수, 0부터 9까지 순열 만들기 코드
0부터 9까지 총 10개의 숫자로 만들 수 있는 순열의 개수는 8877690개이다. 아래 코드는 반복하지 않는 수를 txt 파일로 저장하는 파이썬 코드이다. from itertools import permutations, chain, islice import math def make_no_repeats(length): my_iter = permutations(range(10), length) no_zero_start_index = math.perm(9, length - 1) no_lead_zeros = islice(my_iter, no_zero_start_index, None) return no_lead_zeros if __name__ == '__main__': my_list = [] iter_no_re..
2023.05.14
no image
[백준 1362번 문제, 파이썬3] 펫
문제 문제 당신은 게임으로 펫을 기르고 있습니다. 이 펫은 웃는 표정, 슬픈 표정을 가지고 있으며, 만약 죽는다면 '드러눕습니다.' 펫에게는 적정 체중이 있습니다. 펫의 실제 체중이 적정 체중의 1/2배를 초과하면서 적정 체중의 2배 미만이라면 펫은 행복합니다. 펫의 실제 체중이 0 이하일 경우 펫은 사망하게 되며, 그 외의 경우 펫은 슬픕니다. 당신은 콘솔을 통해 펫에게 아래의 두 가지 작용을 할 수 있습니다. 'E'와 숫자를 입력해 펫을 운동시킬 수 있습니다. 입력된 숫자(n)만큼의 시간(분; minute)이 지나면 펫의 실제 체중이 n 감소합니다. 'F'와 숫자를 입력해 펫에게 먹이를 줄 수 있습니다. 입력된 숫자(n)만큼 펫에게 먹이를 주면 펫의 실제 체중이 n 증가합니다. 각 작용에 입력할 수 ..
2023.05.14
no image
[백준 7696번 문제, 파이썬3] 반복하지 않는 수
문제 문제 한신이는 어릴 때부터 수에 대한 관심이 남달랐으나 이상하게도 같은 숫자를 두 번 이상 쓰는 것을 굉장히 싫어했다. 그래서 한신이에게 첫 번째 수부터 25번째까지의 수를 적어 보라고 하면 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 23, 24, 25, 26, 27, . . . 과 같이 적어 내었다. n번째 반복 숫자 없는 수를 만들어 보자! 입력 입력은 여러 개의 테스트 케이스로 이루어져 있다. 각 테스트 케이스에는 정수 n(1 ≤ n ≤ 1,000,000)이 주어진다. n = 0인 경우 프로그램을 종료한다. 출력 각 테스트 케이스마다 n번째 반복 숫자 없는 수를 출력한다. 코드 from itertools imp..
2023.05.13
728x90
반응형

문제

문제

세준이는 기말고사를 망쳤다. 세준이는 점수를 조작해서 집에 가져가기로 했다. 일단 세준이는 자기 점수 중에 최댓값을 골랐다. 이 값을 M이라고 한다. 그리고 나서 모든 점수를 점수/M*100으로 고쳤다.

예를 들어, 세준이의 최고점이 70이고, 수학점수가 50이었으면 수학점수는 50/70*100이 되어 71.43점이 된다.

세준이의 성적을 위의 방법대로 새로 계산했을 때, 새로운 평균을 구하는 프로그램을 작성하시오.

입력

첫째 줄에 시험 본 과목의 개수 N이 주어진다. 이 값은 1000보다 작거나 같다. 둘째 줄에 세준이의 현재 성적이 주어진다. 이 값은 100보다 작거나 같은 음이 아닌 정수이고, 적어도 하나의 값은 0보다 크다.

출력

첫째 줄에 새로운 평균을 출력한다. 실제 정답과 출력값의 절대오차 또는 상대오차가 10-2 이하이면 정답이다.


코드

import sys

count = int(sys.stdin.readline())
scores = list(map(int, sys.stdin.readline().split()))

max_score = max(scores)

for i in range(len(scores)):
    scores[i] = (scores[i] / max_score) * 100

print(sum(scores) / len(scores))

해결

생각


참고

링크

 

 

 

728x90
반응형
728x90
반응형

문제

문제

세 개의 자연수 A, B, C가 주어질 때 A × B × C를 계산한 결과에 0부터 9까지 각각의 숫자가 몇 번씩 쓰였는지를 구하는 프로그램을 작성하시오.

예를 들어 A = 150, B = 266, C = 427 이라면 A × B × C = 150 × 266 × 427 = 17037300 이 되고, 계산한 결과 17037300 에는 0이 3번, 1이 1번, 3이 2번, 7이 2번 쓰였다.

입력

첫째 줄에 A, 둘째 줄에 B, 셋째 줄에 C가 주어진다. A, B, C는 모두 100보다 크거나 같고, 1,000보다 작은 자연수이다.

출력

첫째 줄에는 A × B × C의 결과에 0 이 몇 번 쓰였는지 출력한다. 마찬가지로 둘째 줄부터 열 번째 줄까지 A × B × C의 결과에 1부터 9까지의 숫자가 각각 몇 번 쓰였는지 차례로 한 줄에 하나씩 출력한다.


코드

from collections import Counter
import sys

a = int(sys.stdin.readline())
b = int(sys.stdin.readline())
c = int(sys.stdin.readline())

total = a * b * c
# 숫자 3개를 곱한 값을 문자열로 만들어서 문자열의 각 문자가 얼마나 있는지
# 딕셔너리 형태로 Counter 클래스가 만들어준다
counter = Counter(str(total))

for i in range(10):
    # 카운터 객체에서 key를 통해 value를 반환받는데
    # 만약 key가 없다면 None을 반환받는다.
    result = counter.get(str(i))
    if result is None:
        print(0)
    else:
        print(result)

해결

생각


참고

링크

 

 

 

728x90
반응형
728x90
반응형

문제

문제

두 자연수 A와 B가 있을 때, A%B는 A를 B로 나눈 나머지 이다. 예를 들어, 7, 14, 27, 38을 3으로 나눈 나머지는 1, 2, 0, 2이다. 

수 10개를 입력받은 뒤, 이를 42로 나눈 나머지를 구한다. 그 다음 서로 다른 값이 몇 개 있는지 출력하는 프로그램을 작성하시오.

입력

첫째 줄부터 열번째 줄 까지 숫자가 한 줄에 하나씩 주어진다. 이 숫자는 1,000보다 작거나 같고, 음이 아닌 정수이다.

출력

첫째 줄에, 42로 나누었을 때, 서로 다른 나머지가 몇 개 있는지 출력한다.


코드

print(len(set([i % 42for i in[int(input())for _ in range(10)]])))

해결

먼저 10개를 숫자로 입력을 받고 그걸 42로 나눠서 set에 넣는다 set에 넣으면 중복된건 사라지기 때문에 서로 다른 나머지가 몇 개 있는지 쉽게 얻을 수 있다.


참고

링크

 

 

 

728x90
반응형
728x90
반응형

문제

문제

컴퓨터를 제조하는 회사인 KOI 전자에서는 제조하는 컴퓨터마다 6자리의 고유번호를 매긴다. 고유번호의 처음 5자리에는 00000부터 99999까지의 수 중 하나가 주어지며 6번째 자리에는 검증수가 들어간다. 검증수는 고유번호의 처음 5자리에 들어가는 5개의 숫자를 각각 제곱한 수의 합을 10으로 나눈 나머지이다.

예를 들어 고유번호의 처음 5자리의 숫자들이 04256이면, 각 숫자를 제곱한 수들의 합 0+16+4+25+36 = 81 을 10으로 나눈 나머지인 1이 검증수이다.

입력

첫째 줄에 고유번호의 처음 5자리의 숫자들이 빈칸을 사이에 두고 하나씩 주어진다.

출력

첫째 줄에 검증수를 출력한다.


코드

import sys

line = map(int, sys.stdin.readline().split())
line = [i ** 2 for i in line]
print(sum(line) % 10)

해결

생각


참고

링크

 

 

 

728x90
반응형
728x90
반응형

문제

문제

알파벳 소문자로만 이루어진 단어 S가 주어진다. 각각의 알파벳에 대해서, 단어에 포함되어 있는 경우에는 처음 등장하는 위치를, 포함되어 있지 않은 경우에는 -1을 출력하는 프로그램을 작성하시오.

입력

첫째 줄에 단어 S가 주어진다. 단어의 길이는 100을 넘지 않으며, 알파벳 소문자로만 이루어져 있다.

출력

각각의 알파벳에 대해서, a가 처음 등장하는 위치, b가 처음 등장하는 위치, ... z가 처음 등장하는 위치를 공백으로 구분해서 출력한다.

만약, 어떤 알파벳이 단어에 포함되어 있지 않다면 -1을 출력한다. 단어의 첫 번째 글자는 0번째 위치이고, 두 번째 글자는 1번째 위치이다.


코드

answer = [-1 for _ in range(26)]    # 출력할 배열을 -1로 초기화
line = [i for i in input()]    # 문자열을 입력받아 각각의 문자로 리스트에 넣는다

for i, v in enumerate(line):    # i는 인덱스, v는 값
    # 97은 a의 아스키코드 문자에서 97을 빼게 되면 a일경우 0 b일 경우 1이 된다
    # 결론적으로 a, b, .... z 순서대로 배열에 넣을 수 있다
    if answer[ord(v) - 97] == -1:    
        answer[ord(v) - 97] = i    # 배열 초기화 값이 -1 이므로 -1일 때만 i를 넣는다

print(*answer)    # *을 넣으면 속성값만 반환받아 출력할 수 있다

해결

생각


참고

링크

 

 

 

728x90
반응형
728x90
반응형

0부터 9까지 총 10개의 숫자로 만들 수 있는 순열의 개수는 8877690개이다.

아래 코드는 반복하지 않는 수를 txt 파일로 저장하는 파이썬 코드이다.

from itertools import permutations, chain, islice
import math


def make_no_repeats(length):
    my_iter = permutations(range(10), length)
    no_zero_start_index = math.perm(9, length - 1)
    no_lead_zeros = islice(my_iter, no_zero_start_index, None)

    return no_lead_zeros


if __name__ == '__main__':
    my_list = []
    iter_no_repeats = chain(*map(make_no_repeats, range(1, 11)))
    while True:
        try:
            my_list.append(int(''.join(map(str, next(iter_no_repeats)))))
        except StopIteration:
            break

    print(len(my_list))
    with open('test.txt', 'w') as f:
        f.write(str(my_list))

 

https://drive.google.com/file/d/1rX3Ohzw39R0q2Iv4AhPJg6swxDdczjDc/view?usp=sharing 

 

반복하지않는수.txt

 

drive.google.com

 

위 링크는 반복하지 않는 수를 txt 파일로 저장한걸 구글 드라이브로 올려뒀다... 이거 그냥 게시글에 복붙하니까 안되서 그냥 심심한김에 올려본다

728x90
반응형
728x90
반응형

문제

문제

당신은 게임으로 펫을 기르고 있습니다. 이 펫은 웃는 표정, 슬픈 표정을 가지고 있으며, 만약 죽는다면 '드러눕습니다.'

펫에게는 적정 체중이 있습니다. 펫의 실제 체중이 적정 체중의 1/2배를 초과하면서 적정 체중의 2배 미만이라면 펫은 행복합니다. 펫의 실제 체중이 0 이하일 경우 펫은 사망하게 되며, 그 외의 경우 펫은 슬픕니다.

당신은 콘솔을 통해 펫에게 아래의 두 가지 작용을 할 수 있습니다.

  1. 'E'와 숫자를 입력해 펫을 운동시킬 수 있습니다. 입력된 숫자(n)만큼의 시간(분; minute)이 지나면 펫의 실제 체중이 n 감소합니다.
  2. 'F'와 숫자를 입력해 펫에게 먹이를 줄 수 있습니다. 입력된 숫자(n)만큼 펫에게 먹이를 주면 펫의 실제 체중이 n 증가합니다.

각 작용에 입력할 수 있는 숫자는 1 이상, 999 이하의 정수입니다. 매 작용이 끝날 때마다 펫은 자신의 상태를 표시하며, 펫이 중간에 죽는다면 이후의 작용은 무시됩니다.

입력

입력은 번호를 가진 시나리오들로 구성됩니다. 시나리오는 1번부터 시작되며 1씩 증가합니다.

적정 체중(o)와 실제 체중(w)가 한 줄에 입력됨으로써 시나리오가 시작됩니다(10 ≤ o, w ≤ 1000). 그 다음 줄부터 펫에 가할 작용이 한 줄에 하나씩 주어지며, "# 0"을 마지막 줄로 하여 시나리오가 종료됩니다. "# 0"은 처리하지 않습니다.

펫에게 가할 각 작용은 'E' 또는 'F'로 시작하며, 공백을 두고 숫자 n (1 ≤ n ≤ 999)이 주어집니다.

모든 시나리오가 끝나면 "0 0"이 입력되며, "0 0"은 처리하지 않습니다.

출력

각 시나리오에 대하여, 시나리오 번호와 모든 작용이 완료된 후 펫의 상태를 공백으로 구분하여 한 줄씩 출력합니다.

  • 행복한 경우, ":-)"을 출력합니다.
  • 슬픈 경우 ":-("을 출력합니다.
  • 사망한 경우 "RIP"를 출력합니다.

코드

import sys


class Pet:
    def __init__(self, o, w):
        self.o = o
        self.w = w
        self.is_alive = True

    def action(self, typeof, value):
        if typeof == 'F':
            self.w += value
        elif typeof == 'E':
            self.w -= value

        if self.w <= 0:
            self.is_alive = False

    def state(self):
        if not self.is_alive:
            return 'RIP'
        elif self.o * 0.5 < self.w < self.o * 2:
            return ':-)'
        else:
            return ':-('


if __name__ == '__main__':
    count = 0
    while True:
        o, w = map(int, input().split())
        if o == 0 and w == 0:
            break

        pet = Pet(o, w)
        count += 1

        while True:
            typeof, value = sys.stdin.readline().split()
            if typeof == '#' and value == '0':
                print(count, pet.state())
                break

            pet.action(typeof, int(value))

해결

펫을 클래스로 만들어서 밥줄때와 상태에 대한 작용을 하는 메서드를 만들었다.

이 문제의 함정은 출력과 상태 두가지라고 생각한다...

 

우선 입출력 테스트케이스인데 출력을보라

1 :-)
2 :-(

왜 그렇게 생각했는지 모르겠는데

1이랑 2가 그냥 순서인줄알고 :-) :-(만 출력했었다... 그런데도 계속 틀렸습니다만 떠서 왜 틀렸는지도 모르고 ㅋㅋㅋㅋ

 

암튼 두번째 함정은

한번이라도 현재 몸무게가 0이하가 되버리면 죽어버린 관계로 밥을 주더라도 다시 살아나지 않는다... RIP

 

위 두 함정을 잘  생각하고 만들면 가볍게 구현 문제를 풀 수 있을거다


참고

링크

 

 

 

 

728x90
반응형
728x90
반응형

문제

문제

한신이는 어릴 때부터 수에 대한 관심이 남달랐으나 이상하게도 같은 숫자를 두 번 이상 쓰는 것을 굉장히 싫어했다.

그래서 한신이에게 첫 번째 수부터 25번째까지의 수를 적어 보라고 하면

1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 23, 24, 25, 26, 27, . . .

과 같이 적어 내었다.

n번째 반복 숫자 없는 수를 만들어 보자!

입력

입력은 여러 개의 테스트 케이스로 이루어져 있다. 각 테스트 케이스에는 정수 n(1 ≤ n ≤ 1,000,000)이 주어진다. n = 0인 경우 프로그램을 종료한다.

출력

각 테스트 케이스마다 n번째 반복 숫자 없는 수를 출력한다.


코드

from itertools import permutations, chain, islice
import math
import sys


def make_no_repeats(length):
    # 0부터 9까지 숫자들로 길이만큼 만들 수 있는 중복되지 않는 순열을 만든다
    my_iter = permutations(range(10), length)

    # 만든 순열 이터레이터에서 islice 메서드로 0이 맨 앞에 오는 경우를 제거하는데
    # 결론적으로 이전에 만들었던 값과 숫자로 볼 때 같은 값을 제거하게 된다

    # 1~9까지 숫자로 1자리 숫자를 만들게 되면 1, 2, 3, 4, 5, 6, 7, 8, 9 라는 순열이 만들어지는데
    # 우리는 0도 사용하면서 반복하지 않는 수를 만들어야한다 그렇게 2자리 숫자를 만들게 되면
    # (0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6), (0, 7), (0, 8), (0, 9), (1, 0), (1, 2), (1, 3),
    # (1, 4), (1, 5), (1, 6), (1, 7), (1, 8), (1, 9).... 이러한 순열이 만들어진다
    # 9p1은 9이다. 2자리로 만들어진 순열에서 앞에 9개를 지우게 되면
    # (1, 0), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (1, 7), (1, 8), (1, 9).... 이러한 순열이 만들어지기 때문이다

    no_zero_start_index = math.perm(9, length - 1)
    
    # 그래서 순열 이터레이터 객체에서 0으로 시작하지 않는 값들로만 잘라서 반환한다.
    no_lead_zeros = islice(my_iter, no_zero_start_index, None)
    
    return no_lead_zeros


if __name__ == '__main__':
    while True:
        count = int(sys.stdin.readline())  # 0을 입력받을 때 까지 반복하면서 입력을 받는다
        if count == 0:
            break

        # 반복하지 않는 수 이터레이터 객체를 만든다. 이터레이터 객체는 실제 값을 갖고 있지 않는다.
        # 백준의 테스트 케이스는 1 <= n <= 1,000,000 이기 때문에 사실은 range(1, 9) 만 해도 된다.
        # 1자리수 부터 9876543210 즉 10자리 까지 반복하지 않는 수를 생성하는 이터레이터 객체의 값들을 자리수마다 만들어서 합친다.
        # 각각의 이터레이터들은 0으로 시작하지 않는 순열을 1자리부터 10자리 까지 있으며 그걸 chain으로 합친다
        iter_no_repeats = chain(*map(make_no_repeats, range(1, 11)))

        # 이터레이터 객체의 n 번째 값을 반환받는다.
        result_number = next(islice(iter_no_repeats, count - 1, None))

        # 반환받은 값은 숫자값들이 튜플 형태로 되어있기 때문에 문자로 만들어서 하나로 합친다
        print(''.join(map(str, result_number)))

 

정답은 아니지만 나름 고민했던 코드... 테스트 케이스대로 답은 나오는데 시간초과 때문에 틀린 코드이다...

참고로 1 ~ 9876543210 까지 반복하지 않는 수의 개수는 8,877,690개이다.

import sys


def make_no_repeat_list(max_count):
    my_list = []
    index = 0
    while len(my_list) < max_count:
        index += 1
        if not len(set(str(index))) < len(str(index)):
            my_list.append(index)

    return my_list


if __name__ == '__main__':
    input_list = []
    while True:
        count = int(sys.stdin.readline())
        if count == 0:
            break
        else:
            input_list.append(count)

    no_repeat_list = make_no_repeat_list(max(input_list))

    for i in input_list:
        print(no_repeat_list[i - 1])

해결

이게 실버4 티어라니.. 말도안됨

 

일단 처음 생각했던 방법은 숫자에 같은 숫자가 중복되지만 않으면 될거같아서

숫자를 문자열로 바꾸고 set에 넣은 다음 중복을 제거하고 제거하기 전 길이와 제거 후 길이가 다르면

반복되는 숫자기 때문에

 

그것을 제외하고 만들어지는 반복하지 않는 수를 리스트에 전부 담은

다음 입력되는 n번째 반복하지 않는 수를 인덱스로 접근만 해서

개별로 출력하면 되겠네 싶어서 바로 위 코드대로 했더니 시간초과가 뜨는 것이다

 

간단히 말하면 미리 반복하지 않는 수를 전부 생성 -> n 번째 인덱스만 받아서 접근 후 출력

이렇게 생각했는데 시간초과라니...

 

시간복잡도는 O(n^2) 이긴한데 이것말고는 생각이 안나서 인터넷을 찾아보려고 해도 안나오고

gpt도 이건 어려운지 계속 이건 효율적인 코드입니다만 반복하고 있고

 

결국에는 이틀째 못풀어서 포기하려고 했는데 백준 문제에 원본 출제된곳이 적혀잇었다

 

University > Stanford Local ACM Programming Contest > SLPC 2004 6번

 

저걸 구글에 검색하니까 

 

스택오버플로우에 질문에 답변이 적혀있어서 이걸 해석하기로 했다

 

위 코드는 0부터 9까지 만들 수 있는 순열을 미리 만들어놓는거였다. 사실 반복하지 않는 수가 순열이었는데

이생각을 못했네

 

그러면 숫자로 만들 수 있는 순열은 한자리에서는 0이 최소일거고 최대는 9876543210 일텐데

이걸 어떻게 위 코드에서는 만들었느냐 

 

 

 

0부터 9까지 총 10자리의 수를 가지고 1자리 순열을 만들어보자

0, 1, 2, 3, 4, 5, 6, 7, 8, 9 라는 순열이 만들어질거다

 

문제는 반복하지 않는 수에서 0은 없으니까 0을 제외하고 나머지 수들만 가져가야하는데

9P0은 뭘까 1이다 아무것도 없는 빈 순열 하나만 만들어지기 때문이다

 

그러면 아까 만들었던 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 순열에서 1번째 자리부터 끝까지 가져가면 되지않을까?

그렇게 1, 2, 3, 4, 5, 6, 7, 8, 9 값들을 생성할수있는 이터레이터 객체를 만들었다!!

 

그 다음 이제 두자릿수 순열을 만들어보자

(0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6), (0, 7), (0, 8), (0, 9), (1, 0), (1, 2), (1, 3), .... ,(9, 8)

이러한 순열이 만들어진다

 

9P1은 뭔가 9다 1, 2, 3, 4, 5, 6, 7, 8, 9 라는 순열이란 말이다.

아가 두자릿수 순열의 앞에서부터 9를 제외하면 뭔가?

(1, 0), (1, 2), (1, 3), .... ,(9, 8)이다 그렇게 또 다른 이터레이터 객체를 만들었다!

 

그러니까 만들어지는 순열에서 맨 앞이 0인 경우를 고정하게되면 만들어지는 경우의수는

9P길이-1 과 같다는 뜻이 된다... 이게 원리적으로 왜이렇게 되는지 이해하는게 너무 어려웠다 ㅠㅠㅠㅠ

 

그렇게 만들어지는 이터레이터 객체들을 10개를 합치고 입력받는 N번째 - 1을 합쳐진 이터레이터 객체에서

NEXT로 값을 받게 되면 우리가 답으로 찾아야하는 N번째 반복하지 않는 수를 얻을 수 있다....

 


참고

 

i have a question about this problem. (SLPC 2004 repeatless)

i have 2 codes. i don't know how to calculate time import sys sys.stdin = open('input.txt') ls = [1,2,3,4,5,6,7,8,9]+[0]*999991 number = 10 k = 10 while True: n = int(sys.stdin.readline()) ...

stackoverflow.com

 

주석 없는 버전

from itertools import permutations, chain, islice
import math
import sys


def make_no_repeats(length):
    my_iter = permutations(range(10), length)
    no_zero_start_index = math.perm(9, length - 1)
    no_lead_zeros = islice(my_iter, no_zero_start_index, None)

    return no_lead_zeros


if __name__ == '__main__':
    while True:
        count = int(sys.stdin.readline())
        if count == 0:
            break

        iter_no_repeats = chain(*map(make_no_repeats, range(1, 11)))
        result_number = next(islice(iter_no_repeats, count - 1, None))
        print(''.join(map(str, result_number)))

 

 

728x90
반응형