반응형

https://www.acmicpc.net/problem/10250

 

10250번: ACM 호텔

프로그램은 표준 입력에서 입력 데이터를 받는다. 프로그램의 입력은 T 개의 테스트 데이터로 이루어져 있는데 T 는 입력의 맨 첫 줄에 주어진다. 각 테스트 데이터는 한 행으로서 H, W, N, 세 정수

www.acmicpc.net

문제

ACM 호텔 매니저 지우는 손님이 도착하는 대로 빈 방을 배정하고 있다. 고객 설문조사에 따르면 손님들은 호텔 정문으로부터 걸어서 가장 짧은 거리에 있는 방을 선호한다고 한다. 여러분은 지우를 도와 줄 프로그램을 작성하고자 한다. 즉 설문조사 결과 대로 호텔 정문으로부터 걷는 거리가 가장 짧도록 방을 배정하는 프로그램을 작성하고자 한다.

문제를 단순화하기 위해서 호텔은 직사각형 모양이라고 가정하자. 각 층에 W 개의 방이 있는 H 층 건물이라고 가정하자 (1 ≤ H, W ≤ 99). 그리고 엘리베이터는 가장 왼쪽에 있다고 가정하자(그림 1 참고). 이런 형태의 호텔을 H × W 형태 호텔이라고 부른다. 호텔 정문은 일층 엘리베이터 바로 앞에 있는데, 정문에서 엘리베이터까지의 거리는 무시한다. 또 모든 인접한 두 방 사이의 거리는 같은 거리(거리 1)라고 가정하고 호텔의 정면 쪽에만 방이 있다고 가정한다.

그림 1. H = 6 이고 W = 12 인 H × W 호텔을 간략하게 나타낸 그림

방 번호는 YXX 나 YYXX 형태인데 여기서 Y 나 YY 는 층 수를 나타내고 XX 는 엘리베이터에서부터 세었을 때의 번호를 나타낸다. 즉, 그림 1 에서 빗금으로 표시한 방은 305 호가 된다.

손님은 엘리베이터를 타고 이동하는 거리는 신경 쓰지 않는다. 다만 걷는 거리가 같을 때에는 아래층의 방을 더 선호한다. 예를 들면 102 호 방보다는 301 호 방을 더 선호하는데, 102 호는 거리 2 만큼 걸어야 하지만 301 호는 거리 1 만큼만 걸으면 되기 때문이다. 같은 이유로 102 호보다 2101 호를 더 선호한다.

여러분이 작성할 프로그램은 초기에 모든 방이 비어있다고 가정하에 이 정책에 따라 N 번째로 도착한 손님에게 배정될 방 번호를 계산하는 프로그램이다. 첫 번째 손님은 101 호, 두 번째 손님은 201 호 등과 같이 배정한다. 그림 1 의 경우를 예로 들면, H = 6이므로 10 번째 손님은 402 호에 배정해야 한다.

입력

프로그램은 표준 입력에서 입력 데이터를 받는다. 프로그램의 입력은 T 개의 테스트 데이터로 이루어져 있는데 T 는 입력의 맨 첫 줄에 주어진다. 각 테스트 데이터는 한 행으로서 H, W, N, 세 정수를 포함하고 있으며 각각 호텔의 층 수, 각 층의 방 수, 몇 번째 손님인지를 나타낸다(1 ≤ H, W ≤ 99, 1 ≤ N ≤ H × W).

출력

프로그램은 표준 출력에 출력한다. 각 테스트 데이터마다 정확히 한 행을 출력하는데, 내용은 N 번째 손님에게 배정되어야 하는 방 번호를 출력한다.


# 10250. ACM 호텔

T = int(input())
for tc in range(T):
    H, W, N = map(int, input().split())

    hotel = [[0]*W for _ in range(H)]
    ans = 0

    for j in range(W):
        for i in range(H-1, -1, -1):
            if N == 1:
                if j < 9:
                    print('{}0'.format(H-i), end='')
                else:
                    print('{}'.format(H-i), end='')
                print(j+1)
            if N > 0:
                hotel[i][j] = N
                N -= 1


    # print(hotel)

백준 단계별로 풀어보기 기본 수학 1, 2에 있는 문제들은 수학 능력을 묻는 문제들로, 수학적 계산을 통해 짧은 코드로 답이 나오는 경우가 많은 것 같다.

하지만 나는 수학 똥멍청이라 수학적 규칙을 찾아내는건 힘들다.

내 코드에서는 호텔을 짓고 손님 한분한분 받아서 안내하는 호텔 매니저의 서사가 보이는 것 같다.

 

일단 호텔을 지어줬다. H, W 값을 2차원 배열로 입력받아 가로가 W 세로가 H인 호텔 배열을 만든다

그리고 호텔 손님들 N명을 차례대로 한명씩 넣어주었다. 카운트를 1부터 N까지 할 수도 있겠지만 나는 거꾸로 N부터 한명씩 빼주었다. 딱히 이유는 없고 새로운 변수 만들기 싫어서..

 

hotel[i][j] 인덱스를 탐색하기 위해서 사용한 이중for문은 j 부터 시작되는데 이건 배열을 세로로 탐색하기 위해서!

그리고 높이 같은 경우에는 1층에서 부터 넣어줘야 하기 때문에 거꾸로 돌려줬다

 

만약 호수가 10호대 이하이면(101호 라던가,,,102호 ) 11호 , 12호 로 출력되면 안되니깐 j<9일때 높이 뒤에 0을 넣어주었고

H-i인 이유도 위에서와 마찬가지로 1층부터 출력해야하기 때문!

j+1을 해준거는 인덱스가 0부터 시작하기 때문이다. 요고는 다른 사람들 코드 참조해서 수학적으로 푸는 방법도 나중에 추가로 포스팅 할 예정.. 총총

반응형
반응형

https://www.acmicpc.net/problem/2869

 

2869번: 달팽이는 올라가고 싶다

첫째 줄에 세 정수 A, B, V가 공백으로 구분되어서 주어진다. (1 ≤ B < A ≤ V ≤ 1,000,000,000)

www.acmicpc.net

문제

땅 위에 달팽이가 있다. 이 달팽이는 높이가 V미터인 나무 막대를 올라갈 것이다.

달팽이는 낮에 A미터 올라갈 수 있다. 하지만, 밤에 잠을 자는 동안 B미터 미끄러진다. 또, 정상에 올라간 후에는 미끄러지지 않는다.

달팽이가 나무 막대를 모두 올라가려면, 며칠이 걸리는지 구하는 프로그램을 작성하시오.

입력

첫째 줄에 세 정수 A, B, V가 공백으로 구분되어서 주어진다. (1 ≤ B < A ≤ V ≤ 1,000,000,000)

출력

첫째 줄에 달팽이가 나무 막대를 모두 올라가는데 며칠이 걸리는지 출력한다.


처음 실패한 코드

A, B, V = map(int, input().split())  # A 올라가는 거리 B 미끄러지는 거리 V 나무 길이
day = 0
distance = 0

while True:
    day += 1
    distance += A
    if distance >= V:
        break
    distance -= B


print(day)

답은 나오지만 시간 초과로 실패한 코드다

A,B,V는 1,000,000,000 라... while이 최대 999,999,999번? 까지 돌 수도 있다... 장수 달팽이

 

계산으로 풀어야 한다.

최종코드

A, B, V = map(int, input().split())  # A 올라가는 거리 B 미끄러지는 거리 V 나무 길이

day = 0

if (V-A) % (A-B) == 0:
    day = (V - A) // (A - B) + 1
else:
    day = (V - A) // (A - B) + 2
print(day)

마지막 날은 미끄러지지 않으니깐 나무 길이에서 하루 올라가는 거리만큼을 뺀다

그리고 올라가는 만큼 나눠준다

+1을 해준건 첫날의 카운트가 0이 아니라 1이어야 하기 때문,

+2를 해준건 나무길이 / 올라가는거리 했을 때 소수점이 나오면 올림을 해줘야하기 때문이다.

반응형
반응형

https://www.acmicpc.net/problem/4153

 

4153번: 직각삼각형

입력은 여러개의 테스트케이스로 주어지며 마지막줄에는 0 0 0이 입력된다. 각 테스트케이스는 모두 30,000보다 작은 양의 정수로 주어지며, 각 입력은 변의 길이를 의미한다.

www.acmicpc.net

문제

과거 이집트인들은 각 변들의 길이가 3, 4, 5인 삼각형이 직각 삼각형인것을 알아냈다. 주어진 세변의 길이로 삼각형이 직각인지 아닌지 구분하시오.

입력

입력은 여러개의 테스트케이스로 주어지며 마지막줄에는 0 0 0이 입력된다. 각 테스트케이스는 모두 30,000보다 작은 양의 정수로 주어지며, 각 입력은 변의 길이를 의미한다.

출력

각 입력에 대해 직각 삼각형이 맞다면 "right", 아니라면 "wrong"을 출력한다.


# 직각삼각형

while True:
    num = list(map(int,input().split()))
    if sum(num) == 0:
        break
    max_num = max(num)

    add = 0

    for i in range(3):
        if num[i] != max_num:
            add += num[i]*num[i]


    if max_num*max_num == add:
        print('right')
    else:
        print('wrong')

피타고라스의 정의를 사용해서 문제를 풀어야한다!

가장 큰 숫자를 미리 변수에 넣어두고 나머지 두 숫자를 제곱해서 더한 후

숫자가 같으면 right 다르면 wrong을 출력하도록 하였다.

반응형
반응형

https://www.acmicpc.net/problem/3009

 

3009번: 네 번째 점

세 점이 주어졌을 때, 축에 평행한 직사각형을 만들기 위해서 필요한 네 번째 점을 찾는 프로그램을 작성하시오.

www.acmicpc.net

문제

세 점이 주어졌을 때, 축에 평행한 직사각형을 만들기 위해서 필요한 네 번째 점을 찾는 프로그램을 작성하시오.

입력

세 점의 좌표가 한 줄에 하나씩 주어진다. 좌표는 1보다 크거나 같고, 1000보다 작거나 같은 정수이다.

출력

직사각형의 네 번째 점의 좌표를 출력한다.


# 네 번째 점

dotx_1, doty_1 = map(int,input().split())
dotx_2, doty_2 = map(int,input().split())
dotx_3, doty_3 = map(int,input().split())

x = [dotx_1, dotx_2, dotx_3]
y = [doty_1, doty_2, doty_3]

for i in range(3):
    if x.count(x[i]) == 1:
        print(x[i], end =' ')
for i in range(3):
    if y.count(y[i]) == 1:
        print(y[i])

처음에는 빈 리스트를 만들고 첫번째 점을 넣은 후 같은 값이 들어오면 해당값을 빼고 다른 값이 들어오면 해당값을 리스트에 더한 후 최후에 남은 값을 출력하도록 짜려고 했는데

그냥 리스트에 다 넣고 개수가 하나인 것을 출력하는게 훨씬 쉽다는걸 너무 늦게 알았다.

반응형
반응형

https://www.acmicpc.net/problem/1085

 

1085번: 직사각형에서 탈출

한수는 지금 (x, y)에 있다. 직사각형은 각 변이 좌표축에 평행하고, 왼쪽 아래 꼭짓점은 (0, 0), 오른쪽 위 꼭짓점은 (w, h)에 있다. 직사각형의 경계선까지 가는 거리의 최솟값을 구하는 프로그램

www.acmicpc.net

문제

한수는 지금 (x, y)에 있다. 직사각형은 각 변이 좌표축에 평행하고, 왼쪽 아래 꼭짓점은 (0, 0), 오른쪽 위 꼭짓점은 (w, h)에 있다. 직사각형의 경계선까지 가는 거리의 최솟값을 구하는 프로그램을 작성하시오.

입력

첫째 줄에 x, y, w, h가 주어진다.

출력

첫째 줄에 문제의 정답을 출력한다.


# 직사각형에서 탈출

x, y, w, h = map(int, input().split())

min =1000

if x < min:
    min = x
if y < min:
    min = y
if w - x < min:
    min = w-x
if h - y < min:
    min = h-y

print(min)

대각선 길이를 고려해 줄 필요가 없으므로 -만으로 단순하게 표현할 수 있었다

첫 min값이 1000인 이유는 제한사항이 1<= w, h <= 1,000이라서!

 

기본 수학2의 소수문제가 점점 풀기 어려워져서

일단 소수로부터 탈출했다.

내가 풀기에 어렵지 않은 알고리즘을 풀면 스트레스가 풀리는 기분이다.

반응형
반응형

https://www.acmicpc.net/problem/11653

 

11653번: 소인수분해

첫째 줄에 정수 N (1 ≤ N ≤ 10,000,000)이 주어진다.

www.acmicpc.net

문제

정수 N이 주어졌을 때, 소인수분해하는 프로그램을 작성하시오.

입력

첫째 줄에 정수 N (1 ≤ N ≤ 10,000,000)이 주어진다.

출력

N의 소인수분해 결과를 한 줄에 하나씩 오름차순으로 출력한다. N이 1인 경우 아무것도 출력하지 않는다.


# 소인수분해

N = int(input())
num = N
factorizaton = []
i = 2
while num > 1:
    if num % i == 0:
        num = num//i
        factorizaton.append(i)
        continue
    i += 1

for i in factorizaton:
    print(i)

N으로 입력값을 받고 num에 N값을 넣어 num 값을 나눠가며 계산했다

지금 생각해보면 그냥 N을 이용했어도 됐을 것 같다

num이 2부터 돌면서 나머지가 0이 되면(나눠지면) factorization리스트에 값을 추가해주고

최종적으로 factorization을 하나씩 출력해줬다

반응형
반응형

https://www.acmicpc.net/problem/2581

 

2581번: 소수

M이상 N이하의 자연수 중 소수인 것을 모두 찾아 첫째 줄에 그 합을, 둘째 줄에 그 중 최솟값을 출력한다.  단, M이상 N이하의 자연수 중 소수가 없을 경우는 첫째 줄에 -1을 출력한다.

www.acmicpc.net

문제

자연수 M과 N이 주어질 때 M이상 N이하의 자연수 중 소수인 것을 모두 골라 이들 소수의 합과 최솟값을 찾는 프로그램을 작성하시오.

예를 들어 M=60, N=100인 경우 60이상 100이하의 자연수 중 소수는 61, 67, 71, 73, 79, 83, 89, 97 총 8개가 있으므로, 이들 소수의 합은 620이고, 최솟값은 61이 된다.

입력

입력의 첫째 줄에 M이, 둘째 줄에 N이 주어진다.

M과 N은 10,000이하의 자연수이며, M은 N보다 작거나 같다.

출력

M이상 N이하의 자연수 중 소수인 것을 모두 찾아 첫째 줄에 그 합을, 둘째 줄에 그 중 최솟값을 출력한다.

단, M이상 N이하의 자연수 중 소수가 없을 경우는 첫째 줄에 -1을 출력한다.


M = int(input())
N = int(input())

add = 0
min = 10000
cnt = 0

for sosu in range(M, N+1):
    sosu_check = 0
    for i in range(1,sosu+1):
        if sosu % i == 0:
            sosu_check += 1
    if sosu_check == 2:
        add += sosu
        cnt += 1
        if sosu < min:
            min = sosu
if cnt > 0:
    print(add)
    print(min)
else:
    print(-1)

2021.09.15 - [study/백준] - [백준] 1978번 소수 찾기 : python

 

[백준] 1978번 소수 찾기 : python

https://www.acmicpc.net/problem/1978 1978번: 소수 찾기 첫 줄에 수의 개수 N이 주어진다. N은 100이하이다. 다음으로 N개의 수가 주어지는데 수는 1,000 이하의 자연수이다. www.acmicpc.net 문제 주어진 수 N..

w-world.tistory.com

이전 소수 찾기와 같은 방법으로 소수를 찾아내고

if 문을 사용해서 add min을 찾아내는 코드를 작성하였다.

예제 입력시 답은 나오는데 시간초과로 틀렸다.

 

최종코드

M = int(input())
N = int(input())

add = 0
min = 10000
cnt = 0

for sosu in range(M, N+1):
    sosu_check = 0
    if sosu != 1:
        for i in range(2,sosu):
            if sosu % i == 0:
                sosu_check = -1
                break
        if sosu_check == 0:
            add += sosu
            cnt += 1
            if sosu < min:
                min = sosu
if cnt > 0:
    print(add)
    print(min)
else:
    print(-1)

그래서 한번이라도 나머지가 0이 나오면 소수가 아니기 때문에

sosu % i == 0 이 나오면 break되도록 바꿔 주었다.

M 이 1이 들어올 수도 있으니깐 if sosu != 1 해줘야한다. 안그러면 틀린다.

 

아직 엄청 많은 문제를 풀어본건 아니지만 백준이 swea와 비교했을때 저런 하나의 예외를 잡아야 통과되는 문제가 많은 것 같다. 백준 어렵다

반응형
반응형

https://www.acmicpc.net/problem/1978

 

1978번: 소수 찾기

첫 줄에 수의 개수 N이 주어진다. N은 100이하이다. 다음으로 N개의 수가 주어지는데 수는 1,000 이하의 자연수이다.

www.acmicpc.net

문제

주어진 수 N개 중에서 소수가 몇 개인지 찾아서 출력하는 프로그램을 작성하시오.

입력

첫 줄에 수의 개수 N이 주어진다. N은 100이하이다. 다음으로 N개의 수가 주어지는데 수는 1,000 이하의 자연수이다.

출력

주어진 수들 중 소수의 개수를 출력한다.


# 소수 찾기

N = int(input())
num = list(map(int,input().split()))

sosu = 0
for i in num:
    cnt = 0
    for j in range(1,i+1):
        if i % j == 0:
            cnt += 1
    if cnt == 2:
        sosu += 1

print(sosu)

소수의 개념이 1과 자기자신으로 밖에 나눌 수 없는 수라 j 로 1에서 자기자신까지 돌려서 나머지가 0인 수를 찾아줬다

그리고 나머지가 0인 경우가 2번이면 소수이므로 변수 sosu의 카운트 증가

sosu출력

반응형
반응형

https://www.acmicpc.net/problem/1712

 

1712번: 손익분기점

월드전자는 노트북을 제조하고 판매하는 회사이다. 노트북 판매 대수에 상관없이 매년 임대료, 재산세, 보험료, 급여 등 A만원의 고정 비용이 들며, 한 대의 노트북을 생산하는 데에는 재료비와

www.acmicpc.net

문제

월드전자는 노트북을 제조하고 판매하는 회사이다. 노트북 판매 대수에 상관없이 매년 임대료, 재산세, 보험료, 급여 등 A만원의 고정 비용이 들며, 한 대의 노트북을 생산하는 데에는 재료비와 인건비 등 총 B만원의 가변 비용이 든다고 한다.

예를 들어 A=1,000, B=70이라고 하자. 이 경우 노트북을 한 대 생산하는 데는 총 1,070만원이 들며, 열 대 생산하는 데는 총 1,700만원이 든다.

노트북 가격이 C만원으로 책정되었다고 한다. 일반적으로 생산 대수를 늘려 가다 보면 어느 순간 총 수입(판매비용)이 총 비용(=고정비용+가변비용)보다 많아지게 된다. 최초로 총 수입이 총 비용보다 많아져 이익이 발생하는 지점을 손익분기점(BREAK-EVEN POINT)이라고 한다.

A, B, C가 주어졌을 때, 손익분기점을 구하는 프로그램을 작성하시오.

입력

첫째 줄에 A, B, C가 빈 칸을 사이에 두고 순서대로 주어진다. A, B, C는 21억 이하의 자연수이다.

출력

첫 번째 줄에 손익분기점 즉 최초로 이익이 발생하는 판매량을 출력한다. 손익분기점이 존재하지 않으면 -1을 출력한다.


a, b, c = map(int, input().split())
ans = 1

flag = 1

while True:
    if b > c:
        flag = 0
        break
    if a+(b*ans) < c*ans:
        break
    ans += 1
if flag == 0:
    print(-1)

if flag == 1:
    print(ans)

while문을 사용해 ans의 값을 1에서부터 하나씩 늘려가면서 손익분기점이 맞는지 아닌지 확인하는 코드를 짰다.

flag는 손익분기점이 존재하는지 확인하는 변수로, 하나를 만드는데 드는 비용이 판매비용보다 비쌀 경우 손익분기점이 존재할 수 없으므로 b > c 일때 flag가 0으로 바뀌도록 하였다.

코드는 잘 돌아가나, 예제 3번이 시간초과로 해결이 안된다. 지금도 파이참에서 돌려놓고 이 글을 다 쓰는 지금까지 답이 안나왔다. 시간초과를 해결해야 했다.

f a < (c-b)*ans:
        break
    ans += 1

이렇게 바꾸면 *ans를 한번밖에 안하니깐 시간이 좀 줄어들지 않을까? 싶었지만 도찐개찐이었다.

 

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

if b > c:
    print(-1)

else : print((a//(c-b))+1)

그러다 이렇게 계산할 수 있다는걸 찾아냈는데....!

ZeroDivisionError가 발생했다 아무래도 테스트케이스 중 b와 c 가 같은 경우가 있는가보다

최종코드

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

if b >= c:
    print(-1)

else : print((a//(c-b))+1)

b = c 라는건 결국 손익분기점에 도달할 수 없다는거니깐 >=로 부등호를 변경해줬다

잘 작동!

반응형
반응형

https://www.acmicpc.net/problem/1316

 

1316번: 그룹 단어 체커

그룹 단어란 단어에 존재하는 모든 문자에 대해서, 각 문자가 연속해서 나타나는 경우만을 말한다. 예를 들면, ccazzzzbb는 c, a, z, b가 모두 연속해서 나타나고, kin도 k, i, n이 연속해서 나타나기 때

www.acmicpc.net

문제

그룹 단어란 단어에 존재하는 모든 문자에 대해서, 각 문자가 연속해서 나타나는 경우만을 말한다. 예를 들면, ccazzzzbb는 c, a, z, b가 모두 연속해서 나타나고, kin도 k, i, n이 연속해서 나타나기 때문에 그룹 단어이지만, aabbbccb는 b가 떨어져서 나타나기 때문에 그룹 단어가 아니다.

단어 N개를 입력으로 받아 그룹 단어의 개수를 출력하는 프로그램을 작성하시오.

입력

첫째 줄에 단어의 개수 N이 들어온다. N은 100보다 작거나 같은 자연수이다. 둘째 줄부터 N개의 줄에 단어가 들어온다. 단어는 알파벳 소문자로만 되어있고 중복되지 않으며, 길이는 최대 100이다.

출력

첫째 줄에 그룹 단어의 개수를 출력한다.


T = int(input())
cnt = 0

for tc in range(T):
    text = input()
    flag = 'T'

    for i in range(len(text)):
        if i < len(text)-2:
            if text[i] != text[i+1]:
                for j in range(i+1,len(text)):
                    if text[i] == text[j]:
                        flag = 'F'
    if flag == 'T':
        cnt += 1

print(cnt)

flag라는 변수를 사용해서 T/F를 구분하고 만약 T 일 경우 cnt가 증가하게 했다

변수를 사용하지 않고 함수를 통해 참/거짓을 반환하게 해도 풀 수 있을 것 같다.

반응형

+ Recent posts