728x90
사전 사용법

1)ctrl + f를 누른뒤 원하는 내용을 입력한다.
2)원하는 내용을 찾으면 해당 문제에 들어가서 어떤건지 찾아본다.

 

2021/01/01 - [python/문제] - [백준/2577]숫자의개수

-문자열 슬라이싱(슬라이스)/ int형변환 / 곱셈

 

2021/01/05 - [python/문제] - [백준/10952]A+B-5

- 문자 int형으로 한줄로 입력받기(map,int,split) / 리스트형으로 한줄로 입력받기

-리스트의 요소 부르기

 

2021/01/05 - [python/문제] - [백준/10951]A+B-4

- try-except / 문자열포매팅 / int형으로 문자열안에서 출력

 

2021/01/23 - [python/문제] - [백준/1712]손익분기점

- 문자열 포매팅

 

2021/01/26 - [python/문제] - [백준/2292]벌집

- 무한반복(while문)

 

2021/01/27 - [python/문제] - [백준/1193]분수찾기

- 절댓값으로 저장하는 함수(abs)

 

2021/02/22 - [python/문제] - [백준,4673]셀프 넘버

- 에러 예외처리함수 (suppress / 한줄로 사용 가능)

 

2021/02/23 - [python/문제] - [백준,1011]Fly me to the Alpha Centauri

-map함수로 한 줄에 입력받기

-def(함수)

 

2021/03/04 - [python/문제] - [백준, 11654] 아스키코드

-ord() : 문자를 아스키코드번호로

- chr() : 아스키코드 번호를 문자로

 

2021/03/04 - [python/문제] - [백준,2675]문자열반복

-print의 end요소 변형

 

2021/03/04 - [python/문제] - [백준,10809]알파벳 찾기

-dict : key 와 value값 list로 추출

-dict : 요소 추가

 

2021.10.28 - [python/문제] - [백준/2231]분해합

-for문 거꾸로

-숫자길이 구하기

 

728x90
728x90

◯문제 링크

 

[백준/2588]곱셈

 

◯코드 미리보기

A = int(input())
B = input()
First = A * int(B[2])
print(First)
Second = A * int(B[1])
print(Second)
Third = A * int(B[0])
print(Third)
print(Third*100 + Second * 10 + First)

설명

A = int(input())
B = input()

일단 문제에서 제시한 A와 B의 값을 받는다. 다만 A는 int형으로, B는 str형으로 받는다.

이렇게 하는 이유는 슬라이싱을 사용하기 위해서이다.

슬라이싱은 []을 활용해서 원하는 위치의 문자를 불러오는 방법으로, 이걸 사용하면 원하는 자리의 값을 개별적으로 꺼낼 수 있다.

 

First = A * int(B[2])
print(First)
Second = A * int(B[1])
print(Second)
Third = A * int(B[0])
print(Third)
print(Third*100 + Second * 10 + First)

ㄴ주어지는 숫자가 세자리라고 했으므로, 처음에는 b의 숫자는 정확히 3칸이다.

중간과정을 보여주기 위해서 int형으로 하나씩 빼주어서 A로 주어진 수를 곱한뒤 출력을 해준다.

이후 각각의 값들을 더해주면 되는데, 10자리와 100의 자리는 고려하지 않고 출력 했었기 때문에 각각을 곱해주어서 더해주어야 한다.

 

 

배운 것

⩥슬라이싱은 list에만 적용되는 것이 아니다.

 

 

 

 

728x90

'python > 문제' 카테고리의 다른 글

[백준,4673]셀프 넘버  (0) 2021.02.22
[백준/15596] 정수 N개의 합  (0) 2021.02.14
[백준,10757]큰 수 A + B  (0) 2021.02.01
[백준/2839]설탕배달  (0) 2021.01.31
[백준,2775]부녀회장이 될테야!  (0) 2021.01.31
728x90

◯문제 링크

 

[백준,10757]큰 수 A + B

 

◯코드 미리보기

a,b = map(int,input().split( ))

print(a+b)

 

 

 

 

설명

너무 간단해서 설명할 것이 있을까 싶긴하다.

a,b = map(int,input().split( ))

이 함수의 알파이자 오메가인 코드이다. split은 괄호 안의 기호를 기준으로 입력값을 구분해서 받을 수 있게 해준다.

이렇게 입력을 받을 때, int형으로 입력을 받고 싶으면 map함수를 사용해주어야 한다.

 

배운 것

 

 

 

 

 

 

 

728x90

'python > 문제' 카테고리의 다른 글

[백준/15596] 정수 N개의 합  (0) 2021.02.14
[백준/2588] 곱셈  (0) 2021.02.03
[백준/2839]설탕배달  (0) 2021.01.31
[백준,2775]부녀회장이 될테야!  (0) 2021.01.31
[백준/10250]ACM 호텔  (0) 2021.01.30
728x90

◯문제 링크

 

[백준/2839]설탕배달

 

◯코드 미리보기

⫷처음에 짠 코드

from sys import exit as kill

N = int(input())
HowMany = list()
BreakCode = True
BreakAllCode = True
Smallest = 3333

for x in range(3334):
    for y in range(1001):
        if N == (3*x + 5*y):
            HowMany.append(x+y)
        if N < 3*x :
            BreakCode = False
            break
        if N < (3*x + 5*y):
            break
    if BreakCode == False:
        break

if len(HowMany) == 0 :
    print("%d"%(-1))
    kill()


for x in range(len(HowMany)):
    if Smallest > HowMany[x] :
        Smallest = HowMany[x]

print(Smallest)

⫷시간단축 코드

from sys import exit as kill

N = int(input())
HowMany = 0
BreakCode = True
BreakAllCode = True
Smallest = 3333

for x in range(3334):
    for y in range(1001):
        if N == (3*x + 5*y):
            HowMany= (x + y)
            BreakCode = False
            break
        if N < (3*x + 5*y):
            break
        if BreakCode == False:
            break
    if BreakCode == False:
        break

if HowMany == 0 :
    print("%d"%(-1))
    kill()



print(HowMany)

 

설명

이 문제를 보자마자 든 생각은 이중for문을 시도해봐야겠다는 것이었다. 그렇게 코드를 짜보기 전에 머릿속으로 예외를 어떻게 처리할지 고민을 하고 있었다.

생각한 방법은 if와 else를 이용해서 n이 나눠 떨어지지 않을 때 -1을 출력하게 하는 것이었는데, 한번에 맞아 떨어지는 조건이 도저히 보이지 않아 고민이었다.

그래서 일단 생각이 난 부분부터 코드를 짜기 시작했는데, 그렇게 하다보니까 문제가 해결되었다.

 

코드에 들어가기에 앞서 핵심이 되는 수식을 소개하겠다. 바로 [N= 3X + 5Y]이다.

N = int(input())
HowMany = list()
BreakCode = True
BreakAllCode = True
Smallest = 3333

이번 코드에서 사용하는 변수들이다. N은 배달해야될 총 킬로그램, HowMany는 수식에 해당되는 X+Y값들이 저장될 list, BreakCode와 BreakAllCode는 각각 반복의 탈출을 위한 변수이다. Smallest는 최솟값을 구하기 위한 변수이다. 자세한건 이따가 최소값을 구하는 코드에서 설명하겠다.

 

for x in range(3334):
    for y in range(1001):
        if N == (3*x + 5*y):
            HowMany.append(x+y)
        if N < 3*x :
            BreakCode = False
            break
        if N < (3*x + 5*y):
            break
    if BreakCode == False:
        break

앞서 말한 수식(N = 3X + 5Y)을 기억하면 for문이 의미하는 것이 무엇인지 알 수 있다. 주의할 점은 바로 범위인데, for문의 범위에서 시작지점을 정하지 않으면 0부터 시작하기 때문에 그냥 3333을 하면 3332까지밖에 들어가지 않는다. 그래서 범위를 3334까지 해주어야한다. 두번째 for문 역시 같은 맥락에서 1001로 범위를 잡았다.

(3333과 1000은 5000을 각각 3과 5로 나누어서 나온 숫자이다.)

두번째 for문 안에는 if 문이 총 3개 있다.

첫번째는 수식에 일치하는 x와 y값을 찾아서 HowMany에 저장하는 코드이다.

두번째는 x값 만으로 N보다 값이 커지기 시작했을 때(최대값을 지났을 때) 이중 for문 전체의 반복을 멈추기 위해 BreakCode를 False로 바꾸고 두번째 for문을 멈추는 코드이다.

세번째는 y값 만으로 N보다 값이 커지기 시작했을 때 두번째 for문의 반복을 멈추는 코드이다.

두번째가 세번째보다 위에 있는 이유는 세번째코드가 먼저 작동할 경우 두번째 if문에 있는 BreakCode변수의 값을 바꾸는 코드가 작동하지 않기 때문이다.

맨 밑에 있는 if문은 첫번째 for문에 속한 if문으로, BreakCode가 False값으로 바뀌었을 때 첫번째 for문을 멈추는 코드이다. 이렇게 되면 이중for문 자체가 멈추게 된다.

 

위의 모든 코드들이 종료되고 나면 HowMany리스트 속에는 가능한 x+y의 값들이 저장되어 있다.

이때 저장된 값들이 하나도 없는 경우는 어떤 경우일까?

바로 문제에서 말하는 '정확하게 N킬로그램을 만들수 없는 경우'이다.

그래서 나오게 된 것이 바로 다음의 코드이다.

from sys import exit as kill
/
.
.
.
/
if len(HowMany) == 0 :
    print("%d"%(-1))
    kill()

먼저 맨 윗줄에 있는 코드부터 살펴보자. 이 코드는 sys모듈에서 exit라는 함수를 kill이라는 이름으로 꺼내온다는 말이다.

보통 이렇게 python내장함수가 아닌 다른 모듈에 있는 함수를 꺼내오는 경우에는 코드의 맨 윗줄에 적는데, 이는 코드를 보게될 다른 인원이 보기 편하게 하기 위해서이다.

 

그 다음 if문을 살펴보자. 조건은 HowMany리스트의 길이가 0일 때를 가리키고 있다. 만약 이중for문에서 해당되는 x+y값이 없을 경우에는 선언된 상태 그대로이기 때문에 길이가 0이되서 조건이 성립된다.

if문 안을 살펴보면, 먼저 문제에서 제시된데로 -1을 출력한다. 그 다음 아까 불러온 kill함수를 사용해서 프로그램 자체를 종료시킨다. 

 

for x in range(len(HowMany)):
    if Smallest > HowMany[x] :
        Smallest = HowMany[x]
print(Smallest)

위의 for문은 최솟값을 구하는 for문이다. 코드 처음에 Smallest의 값을 최대로 잡아뒀기 때문에 if문의 조건에 일치하게 되고, 이후부터는 더 작은 값이 나올때마다 작동하게 되서 최솟값이 나오는 구조이다.

이후 구해진 최솟값을 출력하게되면 문제가 해결된다.

 

 

이렇게 코드를 다 작성하고 제출을 하고 보니, 한가지 재미있는 사실을 알게되었다.

바로 맨 처음 구해진 x+y의 값이(HowMany리스트의 첫번째 인자가) 제일 최솟값이라는 사실이다. 

이것을 이용해서 시간을 단축시킨 코드가 바로 코드미리보기에 나와있는 시간단축코드이다. 

처음에 작성했던 코드와의 차이점은 3가지이다.

HowMany = 0

HowMany를 리스트에서 그냥 변수로 변경,

        if N == (3*x + 5*y):
            HowMany= (x + y)
            BreakCode = False
            break

이중 for문에서 x+y의 값을 처음 찾게되면 for문의 반복을 멈춤,

if HowMany == 0 :
    print("%d"%(-1))
    kill()

그리고 예외의 경우를 for문이 아닌 if 문으로 출력한다는 점이다.

 

 

 

배운 것

⩥break는 해당 루프 하나만을 멈추는 것, 다중루프문에서 전체 루프를 부수려면 위의 방식을 사용해야한다.

 ㄴ다른 함수가 있는지 더 찾아볼 것

⩥sys 모듈에는 프로그램 전체를 멈추는 exit함수가 존재한다. 사용하려면 exit()의 방식으로 사용해야한다.

⩥from import구문을 사용할 때 as를 추가하면 원하는 이름으로 함수를 사용할 수 있다.

 

728x90

'python > 문제' 카테고리의 다른 글

[백준/2588] 곱셈  (0) 2021.02.03
[백준,10757]큰 수 A + B  (0) 2021.02.01
[백준,2775]부녀회장이 될테야!  (0) 2021.01.31
[백준/10250]ACM 호텔  (0) 2021.01.30
[백준/2869]달팽이는 올라가고 싶다  (0) 2021.01.29
728x90

◯문제 링크

 

[백준,2775]부녀회장이 될테야!

 

◯코드 미리보기

T = int(input())
for i in range(T):
    k = int(input())
    n = int(input())
    ZeroFloor = list(range(n))
    ZeroFloor.append(n)
    ZeroFloor.pop(0)
    OverFloor = list(range(len(ZeroFloor)))
    People = 0
    for g in range(k):
        People = 0
        for z in range(len(ZeroFloor)):
            People += ZeroFloor[z]
            OverFloor[z] = People
        for z in range(len(ZeroFloor)):
            ZeroFloor[z],OverFloor[z] = OverFloor[z],ZeroFloor[z]
         
    print(ZeroFloor[n-1])

 

 

설명

이 문제에서 제일 핵심이 되는 문제는 층이 올라갈 수록 새로운 수열이 생긴다는 것이다.

이 부분을 어떻게 해결할지 고민하다가 떠오른 생각이 바로 list를 사용하는 것이다. 

 

T = int(input())
for i in range(T):
    k = int(input())
    n = int(input())

문제에서 제시된 변수들을 입력받는 코드이다. 중간의 T가 들어간 for문은 제시된 test case만큼 코드 전체를 반복하고 종료하는 코드이다.

 

    ZeroFloor = list(range(n))
    ZeroFloor.append(n)
    ZeroFloor.pop(0)
    OverFloor = list(range(len(ZeroFloor)))
    People = 0

ZeroFloor변수는 0층을 나타내는 list이다.

0층은 방번호 만큼 인원이 들어가 있기 때문에 list를 선언 할 때 range를 사용해준다. 이렇게 하면 제일 처음이 0이고 맨 끝이 n-1이다. 

내가 만들고 싶은 리스트는 처음이 1이고 끝이 n이기 때문에 pop과 append를 사용해서 만들어준다.

OverFloor는 아래층의 값들을 더해서 만들어지는 위층을 나타내는 list이다.

People은 방의 인원수를 구하기 위한 변수이다.

문제에서 제시되어 있듯이 b호에 들어가서 살기 위해서는 아래층의 1호부터 b호까지의 인원들의 합만큼의 인원이 들어와야 하는데, 이는 수열의 합이기 때문에 계속해서 덧셈이 되는 변수가 필요하게 된다.

 

    for g in range(k):
        People = 0
        for z in range(len(ZeroFloor)):
            People += ZeroFloor[z]
            OverFloor[z] = People
        for z in range(len(ZeroFloor)):
            ZeroFloor[z],OverFloor[z] = OverFloor[z],ZeroFloor[z]
      

첫번째 for문은 층(k)만큼 코드를 반복시키는 for문이다.

코드가 반복될때마다 사람의 수를 다시 더해줘야 하기 때문에 초기화를 위해서 people의 값을 0으로 만들어주고 다음 for문으로 들어간다.

두번째 for문에서는 0층의 길이만큼 반복을 하게 되는데, 여기서 이전 방들의 인원수 합에 현재 방의 인원을 더해준뒤에 

그 값을 위층에 저장해준다. 중요한 점은 OverFloor 리스트에 값을 추가해줄 때 append가 아니라 []를 이용해서 값을 바꾸어주는 방식을 사용한다는 것이다.

append를 이용하면 리스트가 계속해서 늘어나기 때문에 세번째 for문이 제대로 작동하지 않을 수 있기 때문이다.

세번째 for문에서는 위층과 아래층의 리스트 목록을 서로 swap해준다. 이렇게 되면 두번째 for문에 위층의 역할을 했던 list(OverFloor)의 값이 아래층(ZeroFloor)으로 옮겨지게 된다. 

 

    print(ZeroFloor[n-1])

만약 for문이 끝까지 작동하게 되면, 답을 출력해주면 된다. 주의할 점은 list의 자리는 시작이 1이 아니라 0부터 이므로 n번째 요소를 출력하라고 입력하게되면 오류가 발생하게 된다는 것이다.

 

 

배운 것

⩥list를 선언할 때 range를 사용해주면 원하는 길이만큼의 list를 인자를 가지고 있는 상태로 선언할 수 있다. 이때, list의 인자는 그 자리의 번호랑 동일하다.

⩥for문의 range값의 시작은 0부터이다. list의 순서의 경우에도 동일하다.

⩥a,b = b,a 라고 입력하게 되면 a와 b의 값이 서로 바뀐다. 이를 swap이라고 부른다.

 

 

 

 

 

 

728x90

'python > 문제' 카테고리의 다른 글

[백준,10757]큰 수 A + B  (0) 2021.02.01
[백준/2839]설탕배달  (0) 2021.01.31
[백준/10250]ACM 호텔  (0) 2021.01.30
[백준/2869]달팽이는 올라가고 싶다  (0) 2021.01.29
[백준/1193]분수찾기  (0) 2021.01.27
728x90

◯문제 링크

 

[백준/10250]ACM 호텔

 

◯코드 미리보기

T = int(input())


for i in range (T):
    H,W,N = map(int,input().split( ))
    Y=1
    X=1
    #H:층,W:방번호,N:몇번째 손님
    FullH = H
    while(1):
        if FullH > N :
            Y = N - (FullH - H)
            print("%d%02d"%(Y,X))
            break
        elif FullH == N:
            Y = H
            print("%d%02d"%(Y,X))
            break
        X += 1
        FullH += H

 

 

 

설명

예전에 글이 긴 문제는 그 핵심을 먼저 파악해야 한다고 배웠었다. 그래서 글을 꼼꼼히 읽으면서 맥락부터 파악하려고 노력했다. 그래서 알아낸것이 층들이 먼저 증가하고 층이 꼭대기 층까지 도달하면 방숫자를 하나 증가시킨다는 것이다.

그래서 떠오른 생각이 print를 할 때 Y,X를 따로따로 계산하고 출력할 때만 붙여주면 되겠다는 것이었다.

 

T = int(input())

먼저 문제에서 제시하는 Test횟수를 입력받는다.

 

for i in range(T)

제시받은 T만큼 코드를 반복시킨다.

H,W,N = map(int,input().split( ))
Y=1
X=1
FullH = H

H,W,N은 문제에서 제시된 변수들로, 각각 호텔의 층, 호텔의 방번호, .N번째 손님을 의미한다. 

Y와 X는 문제에서 제시되어있는 YYXX에서 따왔는데, Y는 층을 의미하고 X는 방번호를 의미한다.

CaseBreak는 반복문에서 탈출을 위해 사용한 변수인데, 나중에 해당 부분이 나오면 설명하겠다.

FullH는 H의 값을 계속 증가시키기 위한 변수이다. 사실 이전에 풀었던 문제들에서 while(1)무한루프와 if문을 활용한 조건 반복을 많이 사용했어서 자연스럽게 또 사용하게 되었다. 반복이 걱정되긴했는데, 일단 시간제한이 걸리면 그 때 가서 코드를 수정하자는 마인드였다. 

 

    while(1):
        if FullH > N :
            Y = N - (FullH - H)
            print("%d%02d"%(Y,X))
            break
        elif FullH == N:
            Y = H
            print("%d%02d"%(Y,X))
            break
        X += 1
        FullH += H

이렇게 위에 제시된 변수들을 활용해서 방을 찾는 코드르 짯다.

첫번재 if문부터 설명하자면 FullH가 N보다 커질 때 실행되는 코드이다.

일단 Y값을 구한다. FullH가 N보다 커져서 코드가 실행되는 것이기 때문에 일단 이전에 저장되있는 FullH의 값을 불러오기 위해서 H를 빼주었다. 그리고 그 숫자를 N(N번째 손님)에서 빼준다. 이렇게 하면 이전에 사람이 다 찬 방들이 있는 칸들은 다 빠지고 손님이 들어갈 층이 나오게 된다. FullH를 늘리면서 X값도 1칸씩 늘리면은 방번호가 하나씩 증가하게 된다. 이렇게 구해진 Y와 X를 %d를 활용해서 출력하면 된다. 주의할 점은 X는 두자리로 출력해야 하기 때문에 %02d로 사용해 주어야 한다는 것이다. 

하지만 문제가 하나 있다. 바로 FullH와 N의 같을 경우에는 값이 0이되서 층이 0으로 출력된다는 것이다.

그래서 elif로 조건을 하나 더 세워서 값이 같을 경우를 따로 계산하였다. 위의 부분이랑 다른 것은 표시해야 하는 방이 꼭대기 층이기 때문에 Y값에 H를 넣어주어야 한다. print값은 기존과 동일하다.

 

 

 

이렇게 내 코드는 끝이 났다. 이제부터는 내 친구의 코드인데, 내가 짠 코드보다 간단한 코드라서 올려본다.

Height = 0
Width = 0
Number = 0

for i in range(int(input())):
    Height, Width, Number = map(int, input().split())
    Count = 0
    while(Number > Height):
        if(Number > Height):
            Number -= Height
            Count += 1
    print(Number, end='')
    print("%02d"%(Count+1))

내 코드와는 가장 중요한 점이 다른데, 나는 층이 손님의 수를 넘을 때까지 계속해서 더했다면(일종의 등차수열), 친구는  몇번째 손님인지에서 층을 계속해서 뺏다는 것이다. 결과적으로 더 짧은 코드가 나왔다.

 

배운 것

⩥문자열 포매팅을 사용할 때 자릿수까지 고려해서 출력하는 방법을 배웠다(%02d)

 

728x90

'python > 문제' 카테고리의 다른 글

[백준/2839]설탕배달  (0) 2021.01.31
[백준,2775]부녀회장이 될테야!  (0) 2021.01.31
[백준/2869]달팽이는 올라가고 싶다  (0) 2021.01.29
[백준/1193]분수찾기  (0) 2021.01.27
[백준/2292]벌집  (0) 2021.01.26
728x90

◯문제 링크

 

[백준/2869]달팽이는 올라가고 싶다

 

◯코드 미리보기

정답코드 : 

from math import ceil
A,B,V = map(int,input().split( ))

N=(V-A)/(A-B)

C = ceil(N)
print(C+1)

시간초과 코드 : 

A,B,V = map(int,input().split( ))
N=1

while(1):
    if (V <= (A-B)*N+A):
        print(N+1)
        break
    N += 1

 

 

설명

이 문제는 예전에 책에서 읽어본적이 있는 문제라서 수식을 생각하는데 어렵지 않았다.

그냥 하루가 지날 때 마다  A-B(올라가는 높이 - 내려가는 높이)만큼 증가하고, 마지막 날에는 끝까지 도달하면 내려오지 않으니까 B를 뺄 필요없이 A만 더해주면 된다.

그래서 나온 식이 바로 [V <= (A-B)*N+A] 이다.

주의할 점은, 마지막에 A를 더해준다는 것은 하루가 더 지난다는 것이기 때문에 나온 N의 값에도 1을 더해주어야 한다는 점이다.

이전 문제들에서 반복을 두려워하지 않기로 했기 때문에, 일단 반복을 통해 일수(N)을 증가시키면서 조건에 일치하는 N을 찾는 코드를 만들어 보았다. 

그렇게 해서 나온 코드가 바로 다음의 코드이다.

A,B,V = map(int,input().split( ))
N=1

while(1):
    if (V <= (A-B)*N+A):
        print(N+1)
        break
    N += 1

그러나 이번에는 반복을 사용하면 안되는 것인지 시간초과가 발생했다. 

 

그래서 생각한것이 앞서 말한 수식에는 값이 들어있지 않은 변수가 N하나밖에 없으니까 N의 값을 아예 계산해버리면 되지 않을까라는 생각이다.

이렇게 해서 나온 수식이 [N=(V-A)/(A-B)]이다. 

다만 이 수식을 그대로 사용하면 이전식에서 사용했던 N의 값이랑 동일하게 나오지 않는다.

이전 식에서는 괄호를 사용해서 정수값을 얻을 수 있었는데, 이번에는 등호를 사용하기 때문에 값이 정수로 딱 떨어지지 않는다. 여기서 짚고 넘어가야 할 점은 소수점이 존재한다는 것은 이미 하루가 시작됬다는 것이다. 따라서 올림을 사용해주어야 한다. 여기에 기존의 식 자체가 계산과는 별개로 마지막날 하루가 존재하기 때문에 N의값에 1을 더해주어야한다. 

그래서 나온 코드가 다음의 코드이다.

from math import ceil
A,B,V = map(int,input().split( ))

N=(V-A)/(A-B)

C = ceil(N)
print(C+1)

여기서 올림으로 사용한 함수가 ceil인데, 이 함수는 python내장함수가 아니기 때문에 math모듈에 등록되어 있는 ceil함수를 가져와야 한다. 

이를 위해 사용한 코드가 첫번째줄의 from import 구문이다. 

 

 

 

배운 것

⩥from 모듈 import 함수를 사용하면 모듈에서 사용할 함수를 등록했다.

⩥수식에서 변수가 하나일 경우에는 바로 값을 계산해보는 것도 좋은 방법이다.

 

728x90

'python > 문제' 카테고리의 다른 글

[백준,2775]부녀회장이 될테야!  (0) 2021.01.31
[백준/10250]ACM 호텔  (0) 2021.01.30
[백준/1193]분수찾기  (0) 2021.01.27
[백준/2292]벌집  (0) 2021.01.26
[백준/1712]손익분기점  (0) 2021.01.23
728x90

◯문제 링크

 

[백준/1193]분수찾기

 

◯코드 미리보기

정답 코드 : 

OrderNum = int(input())
MainNum = 1
PlusNum = 2
if OrderNum == 1:
    print("%d/%d"%(1,1))
          
else :
    while (1):
        if OrderNum <= MainNum:
            N = abs(OrderNum - MainNum)
            if SubNum%2==0:
                print("%d/%d"%(SubNum-N,1+N))
            else:
                print("%d/%d"%(1+N,SubNum-N))
           break

        MainNum += PlusNum
        SubNum = PlusNum
        PlusNum +=  

시간초과 코드 :

OrderNum = int(input())
MainNum = 1
SubNum  = 1
PlusNum = 2

          

while (1):
    if OrderNum <= MainNum:
        N = abs(OrderNum - MainNum)
        if SubNum%2==0:
            print("%d/%d"%(SubNum-N,1+N))
            break
        else:
            print("%d/%d"%(1+N,SubNum-N))
            #print(N)
            #print(PlusNum)
            #print(MainNum)
            break

        MainNum += PlusNum
        SubNum = PlusNum
        PlusNum += 1
        print(1)

 

설명

이 문제를 풀면서 제일 먼저 고민했던 것은 규칙을 찾는 것이었다. 그래서 알게된 규칙이 분수와 번호의 관계였다.

문제에서 주어진 표에서, [/]방향 대각선을 1줄 1줄 나누어 보자(번호가 연결되는 줄들이다.).

그러면 각 줄의 끝칸의 분수중(어느 쪽에 있는 것이든) 1이 아닌 부분은 그 줄의 순서와 같다. 이 숫자들을 '줄의 번호'라고 하겠다.

그러면 줄에서 번호가 시작되는 부분이 아닌 끝나는 부분의 번호는 그 줄까지의 PlusNum들의 합과 같다는 사실을 알 수 있다.

이 규칙을 발견하자 이번 문제는 전에 풀었던 벌집 문제와 유사한 부분이 있다는 사실을 알았다. 그래서 그 때 사용했던 방법을 살짝 변형하면 풀 수 있지 않을까란 생각을 했다. 

그래서 고민을 하다가 나온게 바로 다음의 수식이다.

분자 : 1 + (분수번호-번호)의 절댓값
분모 : 줄 번호 - (분수번호-줄번호)의 절댓값

이것을 적용시켜서 나온게 다음의 코드이다.

print("%d/%d"%(SubNum-N,1+N))

먼저 사용된 변수들 부터 설명하자면, SubNum은 입력된 번호가 해당되는 줄의 번호를 의미하고, N은 입력으로 주어지는 분수번호에서 줄번호를 뺀 값의 절댓값을 의미한다. 

처음엔 이렇게만 생각해서 벌집에서 배웠던 코드(수를 더해서 범위를 만들고 주어진 숫자가 그 범위에 해당하면 더함을 멈추고 주어진 코드를 실행하는 코드)를 사용해서 코드를 짯다.

OrderNum = int(input())
MainNum = 1
PlusNum = 2
if OrderNum == 1:
    print("%d/%d"%(1,1))
          
else :
    while (1):
        if OrderNum <= MainNum:
            N = abs(OrderNum - MainNum)
            print("%d/%d"%(1+N,SubNum-N))
           break

        MainNum += PlusNum
        SubNum = PlusNum
        PlusNum +=  

 

결과는 틀렸습니다. 짝수번째 줄에서는 번호가 거꾸로 간다는 것을 생각하지 못했던 것이다.

그래서 출력문에 if를 사용해서 짝수 홀수를 구별해서 출력하는 코드를 작성했다.

OrderNum = int(input())
MainNum = 1
PlusNum = 2
if OrderNum == 1:
    print("%d/%d"%(1,1))
          
else :
    while (1):
        if OrderNum <= MainNum:
            N = abs(OrderNum - MainNum)
            if SubNum%2==0:
                print("%d/%d"%(SubNum-N,1+N))
            else:
                print("%d/%d"%(1+N,SubNum-N))
           break

        MainNum += PlusNum
        SubNum = PlusNum
        PlusNum +=  

여기서 중요한 것은 홀수의 경우에는 분자가 1, 분모가 줄의 번호에 해당하지만, 짝수의 경우에는 분자가 줄의 번호, 분모가 1에 해당한다는 점이다.

 

이렇게 해서 문제를 해결하게 되었다.

 

문제를 풀기는 풀었는데, 찝찝한 점이 남아있었다. 바로 처음 사용된 if문에 대한것이다. 저 if문의 기능은 만약 입력값으로 1이 들어왔을 때 별다른 계산 없이 바로 1/1을 출력하는 코드이다. 

근데 else문 내의 코드 문 자체로도 그냥 될 것 같아서 그렇게 코드를 만들어 보았다.

그런데 이렇게 하니까 시간초과가 발생했다.

왜 그런지 도저히 알 수 가 없어서 넘어갔다.

 

◯배운 것

⩥문자열포매팅을 사용할 때 2개이상을 출력할 때는 괄호와 쉼표를 활용해서 코드를 작성한다.

⩥절댓값으로 저장하는 함수(abs)

 

 

 

 

 

 

 

728x90

'python > 문제' 카테고리의 다른 글

[백준/10250]ACM 호텔  (0) 2021.01.30
[백준/2869]달팽이는 올라가고 싶다  (0) 2021.01.29
[백준/2292]벌집  (0) 2021.01.26
[백준/1712]손익분기점  (0) 2021.01.23
[백준/10951]A+B-4  (0) 2021.01.05

+ Recent posts